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/05/24 03:27:33 UTC
svn commit: r1485917 [1/4] - in /myfaces/core/trunk:
api/src/main/java/javax/faces/application/
api/src/main/java/javax/faces/context/ api/src/main/java/javax/faces/view/
impl/src/main/java/org/apache/myfaces/application/
impl/src/main/java/org/apache/...
Author: lu4242
Date: Fri May 24 01:27:31 2013
New Revision: 1485917
URL: http://svn.apache.org/r1485917
Log:
MYFACES-3729 Implement resource library contracts specification
Added:
myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_LocaleUtils.java
- copied, changed from r1470662, myfaces/core/trunk/api/src/main/java/javax/faces/component/_LocaleUtils.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/ClassLoaderContractResourceLoader.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/DefaultResourceLibraryContractsProvider.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/ExternalContextContractResourceLoader.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/FacesFlowClassLoaderResourceLoader.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/RootExternalContextResourceLoader.java
- copied, changed from r1470662, myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ExternalContextResourceLoader.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/ResourceLibraryContractsProvider.java
- copied, changed from r1470662, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FaceletConfigResourceProvider.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/ResourceLibraryContractsProviderFactory.java
- copied, changed from r1470662, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FaceletConfigResourceProviderFactory.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultResourceLibraryContractsProviderFactory.java
- copied, changed from r1470662, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFaceletConfigResourceProviderFactory.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ResourceHandlerImplContractTest.java (with props)
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/ContractsCreateResourceMyFacesRequestTestCase.java
- copied, changed from r1470662, myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/DefaultContractsConfigMyFacesRequestTestCase.java
- copied, changed from r1470662, myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/javax.faces.contract.xml (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/mylib/ (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/mylib/myjs.js (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/panel.xhtml
- copied, changed from r1470662, myfaces/current22/client-window-example/src/main/webapp/flashKeep1.xhtml
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/ (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/javax.faces.contract.xml (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/mylib/ (with props)
myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/mylib/myjs.js (with props)
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/blue-faces-config.xml
- copied, changed from r1470662, myfaces/current22/client-window-example/src/main/webapp/WEB-INF/faces-config.xml
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/ (with props)
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/ (with props)
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/mylib/ (with props)
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/mylib/myjs.js (with props)
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
- copied, changed from r1470662, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/index.xhtml
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ContractResource.java (with props)
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ContractResourceLoader.java (with props)
Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/application/Resource.java
myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandler.java
myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandlerWrapper.java
myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java
myfaces/core/trunk/api/src/main/java/javax/faces/view/ViewDeclarationLanguage.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/DefaultResourceHandlerSupport.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/resource/InternalClassLoaderResourceLoader.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/impl/DefaultFaceletFactory.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplJsfTest.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ResourceHandlerImplTest.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/AliasResourceMetaImpl.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/BaseResourceHandlerSupport.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ClassLoaderResourceLoader.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ExternalContextResourceLoader.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerSupport.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceImpl.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceLoader.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceLoaderWrapper.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceMeta.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceMetaImpl.java
myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceValidationUtils.java
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/application/Resource.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/application/Resource.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/application/Resource.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/application/Resource.java Fri May 24 01:27:31 2013
@@ -31,7 +31,7 @@ import javax.faces.context.FacesContext;
*
* @since 2.0
*/
-public abstract class Resource
+public abstract class Resource extends ViewResource
{
/**
* This constant is used as the key in the component attribute map of a composite component to
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandler.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandler.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandler.java Fri May 24 01:27:31 2013
@@ -42,6 +42,21 @@ public abstract class ResourceHandler
public static final String RESOURCE_EXCLUDES_PARAM_NAME = "javax.faces.RESOURCE_EXCLUDES";
public static final String RESOURCE_IDENTIFIER = "/javax.faces.resource";
+ /**
+ * @since 2.2
+ */
+ public static final String RESOURCE_CONTRACT_XML = "javax.faces.contract.xml";
+
+ /**
+ * @since 2.2
+ */
+ public static final String WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME = "javax.faces.WEBAPP_CONTRACTS_DIRECTORY";
+
+ /**
+ * @since 2.2
+ */
+ public static final String WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME = "javax.faces.WEBAPP_RESOURCES_DIRECTORY";
+
public abstract Resource createResource(String resourceName);
public abstract Resource createResource(String resourceName, String libraryName);
@@ -55,4 +70,27 @@ public abstract class ResourceHandler
public abstract boolean isResourceRequest(FacesContext context);
public abstract boolean libraryExists(String libraryName);
+
+ /**
+ * @since 2.2
+ * @param resourceId
+ * @return
+ */
+ public Resource createResourceFromId(String resourceId)
+ {
+ return null;
+ }
+
+ /**
+ *
+ * @since 2.2
+ * @param context
+ * @param resourceName
+ * @return
+ */
+ public Resource createViewResource(FacesContext context,
+ String resourceName)
+ {
+ return context.getApplication().getResourceHandler().createResource(resourceName);
+ }
}
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandlerWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandlerWrapper.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandlerWrapper.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/application/ResourceHandlerWrapper.java Fri May 24 01:27:31 2013
@@ -73,6 +73,18 @@ public abstract class ResourceHandlerWra
{
return getWrapped().libraryExists(libraryName);
}
+
+ @Override
+ public Resource createResourceFromId(String resourceId)
+ {
+ return getWrapped().createResourceFromId(resourceId);
+ }
+
+ @Override
+ public Resource createViewResource(FacesContext context, String resourceName)
+ {
+ return getWrapped().createViewResource(context, resourceName);
+ }
public abstract ResourceHandler getWrapped();
}
Added: myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java?rev=1485917&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java (added)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java Fri May 24 01:27:31 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 javax.faces.application;
+
+import java.net.URL;
+
+/**
+ *
+ * @since 2.2
+ */
+public abstract class ViewResource
+{
+ public ViewResource()
+ {
+ }
+
+ public abstract URL getURL();
+}
Propchange: myfaces/core/trunk/api/src/main/java/javax/faces/application/ViewResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java Fri May 24 01:27:31 2013
@@ -18,6 +18,7 @@
*/
package javax.faces.context;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -431,4 +432,35 @@ public abstract class FacesContext
return ctx.isReleased();
}
+
+ /**
+ * @since 2.2
+ * @return
+ */
+ public List<String> getResourceLibraryContracts()
+ {
+ FacesContext ctx = firstInstance.get();
+
+ if (ctx == null)
+ {
+ return Collections.emptyList();
+ }
+
+ return ctx.getResourceLibraryContracts();
+ }
+
+ /**
+ * @since 2.2
+ * @param contracts
+ */
+ public void setResourceLibraryContracts(List<String> contracts)
+ {
+ FacesContext ctx = firstInstance.get();
+
+ if (ctx == null)
+ {
+ return;
+ }
+ ctx.setResourceLibraryContracts(contracts);
+ }
}
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/view/ViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/view/ViewDeclarationLanguage.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/view/ViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/view/ViewDeclarationLanguage.java Fri May 24 01:27:31 2013
@@ -22,6 +22,7 @@ import java.beans.BeanInfo;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -108,4 +109,32 @@ public abstract class ViewDeclarationLan
}
return false;
}
+
+ /**
+ * @since 2.2
+ * @param context
+ * @param taglibURI
+ * @param tagName
+ * @param attributes
+ * @return
+ */
+ public UIComponent createComponent(FacesContext context,
+ String taglibURI,
+ String tagName,
+ Map<String,Object> attributes)
+ {
+ return null;
+ }
+
+ /**
+ * @since 2.2
+ * @param context
+ * @param viewId
+ * @return
+ */
+ public List<String> calculateResourceLibraryContracts(FacesContext context,
+ String viewId)
+ {
+ return null;
+ }
}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/DefaultResourceHandlerSupport.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/DefaultResourceHandlerSupport.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/DefaultResourceHandlerSupport.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/DefaultResourceHandlerSupport.java Fri May 24 01:27:31 2013
@@ -19,13 +19,19 @@
package org.apache.myfaces.application;
import javax.faces.application.ProjectStage;
+import javax.faces.application.ResourceHandler;
import javax.faces.context.FacesContext;
+import org.apache.myfaces.resource.ClassLoaderContractResourceLoader;
+import org.apache.myfaces.resource.ExternalContextContractResourceLoader;
+import org.apache.myfaces.resource.FacesFlowClassLoaderResourceLoader;
import org.apache.myfaces.resource.InternalClassLoaderResourceLoader;
+import org.apache.myfaces.resource.RootExternalContextResourceLoader;
import org.apache.myfaces.resource.TempDirFileCacheResourceLoader;
import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
import org.apache.myfaces.shared.resource.BaseResourceHandlerSupport;
import org.apache.myfaces.shared.resource.ClassLoaderResourceLoader;
+import org.apache.myfaces.shared.resource.ContractResourceLoader;
import org.apache.myfaces.shared.resource.ExternalContextResourceLoader;
import org.apache.myfaces.shared.resource.ResourceLoader;
import org.apache.myfaces.shared.util.WebConfigParamUtils;
@@ -41,11 +47,17 @@ public class DefaultResourceHandlerSuppo
{
private static final String META_INF_RESOURCES = "META-INF/resources";
- private static final String RESOURCES = "/resources";
+ private static final String RESOURCES = "resources";
private static final String META_INF_INTERNAL_RESOURCES = "META-INF/internal-resources";
+ private static final String META_INF_CONTRACTS = "META-INF/contracts";
+ private static final String CONTRACTS = "contracts";
private ResourceLoader[] _resourceLoaders;
+ private ContractResourceLoader[] _contractResourceLoaders;
+
+ private ResourceLoader[] _viewResourceLoaders;
+
public DefaultResourceHandlerSupport()
{
super();
@@ -57,6 +69,9 @@ public class DefaultResourceHandlerSuppo
{
FacesContext facesContext = FacesContext.getCurrentInstance();
+ String directory = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
+ ResourceHandler.WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME, RESOURCES);
+
if (TempDirFileCacheResourceLoader.isValidCreateTemporalFiles(facesContext))
{
//The ExternalContextResourceLoader has precedence over
@@ -69,7 +84,8 @@ public class DefaultResourceHandlerSuppo
!renderedJSFJS.equals(ResourceUtils.JSF_MYFACES_JSFJS_NORMAL))
{
_resourceLoaders = new ResourceLoader[] {
- new TempDirFileCacheResourceLoader(new ExternalContextResourceLoader(RESOURCES)),
+ new TempDirFileCacheResourceLoader(new ExternalContextResourceLoader("/"+directory)),
+ new TempDirFileCacheResourceLoader(new FacesFlowClassLoaderResourceLoader()),
new TempDirFileCacheResourceLoader(
new InternalClassLoaderResourceLoader(META_INF_INTERNAL_RESOURCES)),
new TempDirFileCacheResourceLoader(new ClassLoaderResourceLoader(META_INF_RESOURCES))
@@ -78,7 +94,8 @@ public class DefaultResourceHandlerSuppo
else
{
_resourceLoaders = new ResourceLoader[] {
- new TempDirFileCacheResourceLoader(new ExternalContextResourceLoader(RESOURCES)),
+ new TempDirFileCacheResourceLoader(new ExternalContextResourceLoader("/"+directory)),
+ new TempDirFileCacheResourceLoader(new FacesFlowClassLoaderResourceLoader()),
new TempDirFileCacheResourceLoader(new ClassLoaderResourceLoader(META_INF_RESOURCES))
};
}
@@ -95,7 +112,8 @@ public class DefaultResourceHandlerSuppo
!renderedJSFJS.equals(ResourceUtils.JSF_MYFACES_JSFJS_NORMAL))
{
_resourceLoaders = new ResourceLoader[] {
- new ExternalContextResourceLoader(RESOURCES),
+ new ExternalContextResourceLoader("/"+directory),
+ new FacesFlowClassLoaderResourceLoader(),
new InternalClassLoaderResourceLoader(META_INF_INTERNAL_RESOURCES),
new ClassLoaderResourceLoader(META_INF_RESOURCES)
};
@@ -103,7 +121,8 @@ public class DefaultResourceHandlerSuppo
else
{
_resourceLoaders = new ResourceLoader[] {
- new ExternalContextResourceLoader(RESOURCES),
+ new ExternalContextResourceLoader("/"+directory),
+ new FacesFlowClassLoaderResourceLoader(),
new ClassLoaderResourceLoader(META_INF_RESOURCES)
};
}
@@ -111,4 +130,66 @@ public class DefaultResourceHandlerSuppo
}
return _resourceLoaders;
}
+
+ @Override
+ public ContractResourceLoader[] getContractResourceLoaders()
+ {
+ if (_contractResourceLoaders == null)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+
+ String directory = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
+ ResourceHandler.WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME, CONTRACTS);
+
+ if (directory.startsWith("/"))
+ {
+ throw new IllegalStateException("javax.faces.WEBAPP_CONTRACTS_DIRECTORY cannot start with '/");
+ }
+
+ /* TODO: Implement me!
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+
+ if (TempDirFileCacheResourceLoader.isValidCreateTemporalFiles(facesContext))
+ {
+ _contractResourceLoaders= new ContractResourceLoader[] {
+ new ExternalContextContractResourceLoader(CONTRACTS),
+ new ClassLoaderContractResourceLoader(META_INF_CONTRACTS)
+ };
+ }
+ else
+ {*/
+
+ _contractResourceLoaders= new ContractResourceLoader[] {
+ new ExternalContextContractResourceLoader("/"+directory),
+ new ClassLoaderContractResourceLoader(META_INF_CONTRACTS)
+ };
+ //}
+ }
+ return _contractResourceLoaders;
+ }
+
+ @Override
+ public ResourceLoader[] getViewResourceLoaders()
+ {
+ if (_viewResourceLoaders == null)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (TempDirFileCacheResourceLoader.isValidCreateTemporalFiles(facesContext))
+ {
+ _viewResourceLoaders = new ResourceLoader[] {
+ new RootExternalContextResourceLoader(),
+ new TempDirFileCacheResourceLoader(new FacesFlowClassLoaderResourceLoader())
+ };
+ }
+ else
+ {
+ _viewResourceLoaders = new ResourceLoader[] {
+ new RootExternalContextResourceLoader(),
+ new FacesFlowClassLoaderResourceLoader()
+ };
+ }
+ }
+ return _viewResourceLoaders;
+ }
+
}
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=1485917&r1=1485916&r2=1485917&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 Fri May 24 01:27:31 2013
@@ -40,13 +40,16 @@ import javax.servlet.http.HttpServletRes
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.URL;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import org.apache.myfaces.shared.resource.ContractResource;
+import org.apache.myfaces.shared.resource.ContractResourceLoader;
/**
* DOCUMENT ME!
@@ -85,6 +88,9 @@ public class ResourceHandlerImpl extends
public static final String INIT_PARAM_RESOURCE_BUFFER_SIZE = "org.apache.myfaces.RESOURCE_BUFFER_SIZE";
public static final int INIT_PARAM_RESOURCE_BUFFER_SIZE_DEFAULT = 2048;
+ public static final Pattern LIBRARY_VERSION_CHECKER = Pattern.compile("\\p{Digit}+(_\\p{Digit}*)*");
+ public static final Pattern RESOURCE_VERSION_CHECKER = Pattern.compile("\\p{Digit}+(_\\p{Digit}*)*\\..*");
+
private Boolean _allowSlashLibraryName;
private int _resourceBufferSize = -1;
@@ -108,6 +114,13 @@ public class ResourceHandlerImpl extends
{
Resource resource = null;
+ if (resourceName.charAt(0) == '/')
+ {
+ // If resourceName starts with '/', remove that character because it
+ // does not have any meaning (with and without should point to the
+ // same resource).
+ resourceName = resourceName.substring(1);
+ }
if (!ResourceValidationUtils.isValidResourceName(resourceName))
{
return null;
@@ -117,45 +130,248 @@ public class ResourceHandlerImpl extends
{
return null;
}
-
+ FacesContext facesContext = FacesContext.getCurrentInstance();
if (contentType == null)
{
//Resolve contentType using ExternalContext.getMimeType
- contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(resourceName);
+ contentType = facesContext.getExternalContext().getMimeType(resourceName);
}
- final String localePrefix = getLocalePrefixForLocateResource();
-
- // check cache
- if(getResourceLoaderCache().containsResource(resourceName, libraryName, contentType, localePrefix))
+ final String localePrefix = getLocalePrefixForLocateResource(facesContext);
+ final List<String> contracts = facesContext.getResourceLibraryContracts();
+ boolean found = false;
+ String contractSelected = null;
+ String contractPreferred = getContractNameForLocateResource(facesContext);
+
+ // Check cache:
+ //
+ // Contracts are on top of everything, because it is a concept that defines
+ // resources in a application scope concept. It means all resources in
+ // /resources or /META-INF/resources can be overriden using a contract. Note
+ // it also means resources under /META-INF/flows can also be overriden using
+ // a contract.
+
+ // Check first the preferred contract if any. If not found, try the remaining
+ // contracts and finally if not found try to found a resource without a
+ // contract name.
+ if (contractPreferred != null)
+ {
+ if (getResourceLoaderCache().containsResource(
+ resourceName, libraryName, contentType, localePrefix, contractPreferred))
+ {
+ contractSelected = contractPreferred;
+ found = true;
+ }
+ }
+ if (!found && !contracts.isEmpty())
+ {
+ // Try to get resource but try with a contract name
+ for (String contract : contracts)
+ {
+ if (getResourceLoaderCache().containsResource(
+ resourceName, libraryName, contentType, localePrefix, contract))
+ {
+ contractSelected = contract;
+ found = true;
+ break;
+ }
+ }
+ }
+ // Only if no contract preferred try without it.
+ if (!found)
+ {
+ // Try to get resource without contract name
+ found = getResourceLoaderCache().containsResource(resourceName, libraryName, contentType, localePrefix);
+ }
+
+ if(found)
{
ResourceValue resourceValue = getResourceLoaderCache().getResource(
- resourceName, libraryName, contentType, localePrefix);
+ resourceName, libraryName, contentType, localePrefix, contractSelected);
resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
getResourceHandlerSupport(), contentType);
}
else
{
- for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
+ boolean resolved = false;
+ // Try preferred contract first
+ if (contractPreferred != null)
{
- ResourceMeta resourceMeta = deriveResourceMeta(loader, resourceName, libraryName, localePrefix);
-
- if (resourceMeta != null)
+ for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
{
- resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
+ ResourceMeta resourceMeta = deriveResourceMeta(loader, resourceName, libraryName,
+ localePrefix, contractPreferred);
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
- // cache it
- getResourceLoaderCache().putResource(resourceName, libraryName, contentType,
- localePrefix, resourceMeta, loader);
- break;
+ // cache it
+ getResourceLoaderCache().putResource(resourceName, libraryName, contentType,
+ localePrefix, contractPreferred, resourceMeta, loader);
+ resolved = true;
+ break;
+ }
+ }
+ }
+ if (!resolved && !contracts.isEmpty())
+ {
+ for (ContractResourceLoader loader :
+ getResourceHandlerSupport().getContractResourceLoaders())
+ {
+ for (String contract : contracts)
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(
+ loader, resourceName, libraryName,
+ localePrefix, contract);
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putResource(
+ resourceName, libraryName, contentType,
+ localePrefix, contract, resourceMeta, loader);
+ resolved = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!resolved)
+ {
+ for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(
+ loader, resourceName, libraryName, localePrefix);
+
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(
+ resourceMeta, loader, getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putResource(resourceName, libraryName, contentType,
+ localePrefix, resourceMeta, loader);
+ break;
+ }
}
}
}
-
return resource;
}
+ protected ResourceMeta deriveResourceMeta(ContractResourceLoader resourceLoader,
+ String resourceName, String libraryName, String localePrefix, String contractName)
+ {
+ String resourceVersion = null;
+ String libraryVersion = null;
+ ResourceMeta resourceId = null;
+
+ //1. Try to locate resource in a localized path
+ if (localePrefix != null)
+ {
+ if (null != libraryName)
+ {
+ String pathToLib = localePrefix + '/' + libraryName;
+ libraryVersion = resourceLoader.getLibraryVersion(pathToLib, contractName);
+
+ if (null != libraryVersion)
+ {
+ String pathToResource = localePrefix + '/'
+ + libraryName + '/' + libraryVersion + '/'
+ + resourceName;
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource, contractName);
+ }
+ else
+ {
+ String pathToResource = localePrefix + '/'
+ + libraryName + '/' + resourceName;
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource, contractName);
+ }
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = resourceLoader.createResourceMeta(localePrefix, libraryName,
+ libraryVersion, resourceName, resourceVersion, contractName);
+ }
+ }
+ else
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(localePrefix + '/'+ resourceName, contractName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = resourceLoader.createResourceMeta(localePrefix, null, null,
+ resourceName, resourceVersion, contractName);
+ }
+ }
+
+ if (resourceId != null)
+ {
+ if (!resourceLoader.resourceExists(resourceId))
+ {
+ resourceId = null;
+ }
+ }
+ }
+
+ //2. Try to localize resource in a non localized path
+ if (resourceId == null)
+ {
+ if (null != libraryName)
+ {
+ libraryVersion = resourceLoader.getLibraryVersion(libraryName, contractName);
+
+ if (null != libraryVersion)
+ {
+ String pathToResource = (libraryName + '/' + libraryVersion
+ + '/' + resourceName);
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource, contractName);
+ }
+ else
+ {
+ String pathToResource = (libraryName + '/'
+ + resourceName);
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource, contractName);
+ }
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = resourceLoader.createResourceMeta(null, libraryName,
+ libraryVersion, resourceName, resourceVersion, contractName);
+ }
+ }
+ else
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(resourceName, contractName);
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = resourceLoader.createResourceMeta(null, null, null,
+ resourceName, resourceVersion, contractName);
+ }
+ }
+
+ if (resourceId != null)
+ {
+ if (!resourceLoader.resourceExists(resourceId))
+ {
+ resourceId = null;
+ }
+ }
+ }
+
+ return resourceId;
+ }
+
/**
* This method try to create a ResourceMeta for a specific resource
* loader. If no library, or resource is found, just return null,
@@ -212,8 +428,7 @@ public class ResourceHandlerImpl extends
if (resourceId != null)
{
- URL url = resourceLoader.getResourceURL(resourceId);
- if (url == null)
+ if (!resourceLoader.resourceExists(resourceId))
{
resourceId = null;
}
@@ -262,8 +477,7 @@ public class ResourceHandlerImpl extends
if (resourceId != null)
{
- URL url = resourceLoader.getResourceURL(resourceId);
- if (url == null)
+ if (!resourceLoader.resourceExists(resourceId))
{
resourceId = null;
}
@@ -495,8 +709,12 @@ public class ResourceHandlerImpl extends
protected String getLocalePrefixForLocateResource()
{
+ return getLocalePrefixForLocateResource(FacesContext.getCurrentInstance());
+ }
+
+ protected String getLocalePrefixForLocateResource(FacesContext context)
+ {
String localePrefix = null;
- FacesContext context = FacesContext.getCurrentInstance();
boolean isResourceRequest = context.getApplication().getResourceHandler().isResourceRequest(context);
if (isResourceRequest)
@@ -546,6 +764,31 @@ public class ResourceHandlerImpl extends
}
return localePrefix;
}
+
+ protected String getContractNameForLocateResource(FacesContext context)
+ {
+ String contractName = null;
+ boolean isResourceRequest = context.getApplication().getResourceHandler().isResourceRequest(context);
+
+ if (isResourceRequest)
+ {
+ contractName = context.getExternalContext().getRequestParameterMap().get("con");
+ }
+
+ // Check if the contract has been injected.
+ if (contractName == null)
+ {
+ contractName = (String) context.getAttributes().get(ContractResource.CONTRACT_SELECTED);
+ }
+
+ //Validate
+ if (contractName != null &&
+ !ResourceValidationUtils.isValidContractName(contractName))
+ {
+ return null;
+ }
+ return contractName;
+ }
protected boolean isResourceIdentifierExcluded(FacesContext context, String resourceIdentifier)
{
@@ -577,7 +820,9 @@ public class ResourceHandlerImpl extends
@Override
public boolean libraryExists(String libraryName)
{
- String localePrefix = getLocalePrefixForLocateResource();
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ String localePrefix = getLocalePrefixForLocateResource(facesContext);
+ final List<String> contracts = facesContext.getResourceLibraryContracts();
String pathToLib = null;
@@ -592,6 +837,21 @@ public class ResourceHandlerImpl extends
//Check with locale
pathToLib = localePrefix + '/' + libraryName;
+ if (!contracts.isEmpty())
+ {
+ for (String contract : contracts)
+ {
+ for (ContractResourceLoader loader : getResourceHandlerSupport()
+ .getContractResourceLoaders())
+ {
+ if (loader.libraryExists(pathToLib, contract))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
for (ResourceLoader loader : getResourceHandlerSupport()
.getResourceLoaders())
{
@@ -603,6 +863,21 @@ public class ResourceHandlerImpl extends
}
//Check without locale
+ if (!contracts.isEmpty())
+ {
+ for (String contract : contracts)
+ {
+ for (ContractResourceLoader loader : getResourceHandlerSupport()
+ .getContractResourceLoaders())
+ {
+ if (loader.libraryExists(contract, libraryName))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
for (ResourceLoader loader : getResourceHandlerSupport()
.getResourceLoaders())
{
@@ -711,4 +986,777 @@ public class ResourceHandlerImpl extends
return _resourceBufferSize;
}
+ @Override
+ public Resource createResourceFromId(String resourceId)
+ {
+ Resource resource = null;
+
+ if (resourceId == null)
+ {
+ throw new NullPointerException();
+ }
+
+ // Later in deriveResourceMeta the resourceId is decomposed and
+ // its elements validated properly.
+ if (!ResourceValidationUtils.isValidResourceId(resourceId))
+ {
+ return null;
+ }
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ final List<String> contracts = facesContext.getResourceLibraryContracts();
+ boolean found = false;
+ String contractSelected = null;
+ String contractPreferred = getContractNameForLocateResource(facesContext);
+
+ // Check cache:
+ //
+ // Contracts are on top of everything, because it is a concept that defines
+ // resources in a application scope concept. It means all resources in
+ // /resources or /META-INF/resources can be overriden using a contract. Note
+ // it also means resources under /META-INF/flows can also be overriden using
+ // a contract.
+ if (contractPreferred != null)
+ {
+ if (getResourceLoaderCache().containsResource(
+ resourceId, contractPreferred))
+ {
+ contractSelected = contractPreferred;
+ found = true;
+ }
+ }
+ if (!found && !contracts.isEmpty())
+ {
+ // Try to get resource but try with a contract name
+ for (String contract : contracts)
+ {
+ if (getResourceLoaderCache().containsResource(resourceId, contract))
+ {
+ contractSelected = contract;
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ // Try to get resource without contract name
+ found = getResourceLoaderCache().containsResource(resourceId);
+ }
+
+ if(found)
+ {
+ ResourceValue resourceValue = contractSelected != null ?
+ getResourceLoaderCache().getResource(resourceId, contractSelected) :
+ getResourceLoaderCache().getResource(resourceId);
+
+ //Resolve contentType using ExternalContext.getMimeType
+ String contentType = facesContext.getExternalContext().getMimeType(
+ resourceValue.getResourceMeta().getResourceName());
+
+ resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
+ getResourceHandlerSupport(), contentType);
+ }
+ else
+ {
+ boolean resolved = false;
+ if (contractPreferred != null)
+ {
+ for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(
+ facesContext, loader, resourceId, contractPreferred);
+ if (resourceMeta != null)
+ {
+ String contentType = facesContext.getExternalContext().getMimeType(
+ resourceMeta.getResourceName());
+
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putResource(resourceId, resourceMeta, loader);
+
+ resolved = true;
+ break;
+ }
+ }
+ }
+ if (!resolved && !contracts.isEmpty())
+ {
+ for (ContractResourceLoader loader :
+ getResourceHandlerSupport().getContractResourceLoaders())
+ {
+ for (String contract : contracts)
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(
+ facesContext, loader, resourceId, contract);
+ if (resourceMeta != null)
+ {
+ String contentType = facesContext.getExternalContext().getMimeType(
+ resourceMeta.getResourceName());
+
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putResource(resourceId, resourceMeta, loader);
+
+ resolved = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!resolved)
+ {
+ for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(facesContext, loader, resourceId);
+
+ if (resourceMeta != null)
+ {
+ String contentType = facesContext.getExternalContext().getMimeType(
+ resourceMeta.getResourceName());
+
+ resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putResource(resourceId, resourceMeta, loader);
+ break;
+ }
+ }
+ }
+ }
+ return resource;
+ }
+
+ protected ResourceMeta deriveResourceMeta(FacesContext context, ResourceLoader resourceLoader,
+ String resourceId)
+ {
+ ResourceMeta resourceMeta = null;
+ String token = null;
+ String localePrefix = null;
+ String libraryName = null;
+ String libraryVersion = null;
+ String resourceName = null;
+ String resourceVersion = null;
+
+ // Check if resource exists. It avoids additional
+ // checks and it can be done very quickly because the
+ // loader always uses the resourceId structure to
+ // organize resources. But decompose the resourceId is
+ // even faster.
+ //if (resourceLoader.resourceIdExists(resourceId))
+ //{
+ int lastSlash = resourceId.lastIndexOf('/');
+ if (lastSlash < 0)
+ {
+ //no slashes, so it is just a plain resource.
+ resourceName = resourceId;
+ }
+ else
+ {
+ token = resourceId.substring(lastSlash+1);
+ if (RESOURCE_VERSION_CHECKER.matcher(token).matches())
+ {
+ int secondLastSlash = resourceId.lastIndexOf('/', lastSlash-1);
+ if (secondLastSlash < 0)
+ {
+ secondLastSlash = 0;
+ }
+
+ String rnToken = resourceId.substring(secondLastSlash+1, lastSlash);
+ int lastPoint = rnToken.lastIndexOf('.');
+ if (lastPoint < 0)
+ {
+ //does not match, the token is not a resource version
+ }
+ else
+ {
+ String ext = rnToken.substring(lastPoint);
+ if (token.endsWith(ext))
+ {
+ //It match a versioned resource
+ resourceVersion = token.substring(0,token.length()-ext.length());
+ }
+ }
+ }
+
+ // 1. Extract the library path and locale prefix if necessary
+ int start = 0;
+ int firstSlash = resourceId.indexOf('/');
+
+ // At least one slash, check if the start is locale prefix.
+ String bundleName = context.getApplication().getMessageBundle();
+ //If no bundle set, it can't be localePrefix
+ if (null != bundleName)
+ {
+ token = resourceId.substring(start, firstSlash);
+ //Try to derive a locale object
+ Locale locale = _LocaleUtils.deriveLocale(token);
+
+ // If the locale was derived and it is available,
+ // assume that portion of the resourceId it as a locale prefix.
+ if (locale != null && _LocaleUtils.isAvailableLocale(locale))
+ {
+ localePrefix = token;
+ start = firstSlash+1;
+ }
+ }
+
+ //Check slash again from start
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash < 0)
+ {
+ //no slashes.
+ resourceName = resourceId.substring(start);
+ }
+ else
+ {
+ //check libraryName
+ token = resourceId.substring(start, firstSlash);
+ int minResourceNameSlash = (resourceVersion != null) ?
+ resourceId.lastIndexOf('/', lastSlash-1) : lastSlash;
+ //if (resourceLoader.libraryExists(token))
+ if (start < minResourceNameSlash)
+ {
+ libraryName = token;
+ start = firstSlash+1;
+
+ //Now that libraryName exists, check libraryVersion
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash >= 0)
+ {
+ token = resourceId.substring(start, firstSlash);
+ if (LIBRARY_VERSION_CHECKER.matcher(token).matches())
+ {
+ libraryVersion = token;
+ start = firstSlash+1;
+ }
+ }
+ }
+
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash < 0)
+ {
+ //no slashes.
+ resourceName = resourceId.substring(start);
+ }
+ else
+ {
+ // Check resource version.
+ if (resourceVersion != null)
+ {
+ resourceName = resourceId.substring(start,lastSlash);
+ }
+ else
+ {
+ //no resource version, assume the remaining to be resource name
+ resourceName = resourceId.substring(start);
+ }
+ }
+ }
+ }
+
+ //Check libraryName and resourceName
+ if (resourceName == null)
+ {
+ return null;
+ }
+ if (!ResourceValidationUtils.isValidResourceName(resourceName))
+ {
+ return null;
+ }
+
+ if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
+ libraryName, isAllowSlashesLibraryName()))
+ {
+ return null;
+ }
+
+ // If some variable is "" set it as null.
+ if (localePrefix != null && localePrefix.length() == 0)
+ {
+ localePrefix = null;
+ }
+ if (libraryName != null && libraryName.length() == 0)
+ {
+ libraryName = null;
+ }
+ if (libraryVersion != null && libraryVersion.length() == 0)
+ {
+ libraryVersion = null;
+ }
+ if (resourceName != null && resourceName.length() == 0)
+ {
+ resourceName = null;
+ }
+ if (resourceVersion != null && resourceVersion.length() == 0)
+ {
+ resourceVersion = null;
+ }
+
+ resourceMeta = resourceLoader.createResourceMeta(
+ localePrefix, libraryName, libraryVersion, resourceName, resourceVersion);
+
+ if (resourceMeta != null &&
+ !resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ //}
+ return resourceMeta;
+ }
+
+ protected ResourceMeta deriveResourceMeta(FacesContext context, ContractResourceLoader resourceLoader,
+ String resourceId, String contractName)
+ {
+ ResourceMeta resourceMeta = null;
+ String token = null;
+ String localePrefix = null;
+ String libraryName = null;
+ String libraryVersion = null;
+ String resourceName = null;
+ String resourceVersion = null;
+
+ // Check if resource exists. It avoids additional
+ // checks and it can be done very quickly because the
+ // loader always uses the resourceId structure to
+ // organize resources. But decompose the resourceId is
+ // even faster.
+ //if (resourceLoader.resourceIdExists(resourceId))
+ //{
+ int lastSlash = resourceId.lastIndexOf('/');
+ if (lastSlash < 0)
+ {
+ //no slashes, so it is just a plain resource.
+ resourceName = resourceId;
+ }
+ else
+ {
+ token = resourceId.substring(lastSlash+1);
+ if (RESOURCE_VERSION_CHECKER.matcher(token).matches())
+ {
+ int secondLastSlash = resourceId.lastIndexOf('/', lastSlash-1);
+ if (secondLastSlash < 0)
+ {
+ secondLastSlash = 0;
+ }
+
+ String rnToken = resourceId.substring(secondLastSlash+1, lastSlash);
+ int lastPoint = rnToken.lastIndexOf('.');
+ if (lastPoint < 0)
+ {
+ //does not match, the token is not a resource version
+ }
+ else
+ {
+ String ext = rnToken.substring(lastPoint);
+ if (token.endsWith(ext))
+ {
+ //It match a versioned resource
+ resourceVersion = token.substring(0,token.length()-ext.length());
+ }
+ }
+ }
+
+ // 1. Extract the library path and locale prefix if necessary
+ int start = 0;
+ int firstSlash = resourceId.indexOf('/');
+
+ // At least one slash, check if the start is locale prefix.
+ String bundleName = context.getApplication().getMessageBundle();
+ //If no bundle set, it can't be localePrefix
+ if (null != bundleName)
+ {
+ token = resourceId.substring(start, firstSlash);
+ //Try to derive a locale object
+ Locale locale = _LocaleUtils.deriveLocale(token);
+
+ // If the locale was derived and it is available,
+ // assume that portion of the resourceId it as a locale prefix.
+ if (locale != null && _LocaleUtils.isAvailableLocale(locale))
+ {
+ localePrefix = token;
+ start = firstSlash+1;
+ }
+ }
+
+ //Check slash again from start
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash < 0)
+ {
+ //no slashes.
+ resourceName = resourceId.substring(start);
+ }
+ else
+ {
+ //check libraryName
+ token = resourceId.substring(start, firstSlash);
+ int minResourceNameSlash = (resourceVersion != null) ?
+ resourceId.lastIndexOf('/', lastSlash-1) : lastSlash;
+ //if (resourceLoader.libraryExists(token))
+ if (start < minResourceNameSlash)
+ {
+ libraryName = token;
+ start = firstSlash+1;
+
+ //Now that libraryName exists, check libraryVersion
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash >= 0)
+ {
+ token = resourceId.substring(start, firstSlash);
+ if (LIBRARY_VERSION_CHECKER.matcher(token).matches())
+ {
+ libraryVersion = token;
+ start = firstSlash+1;
+ }
+ }
+ }
+
+ firstSlash = resourceId.indexOf('/', start);
+ if (firstSlash < 0)
+ {
+ //no slashes.
+ resourceName = resourceId.substring(start);
+ }
+ else
+ {
+ // Check resource version.
+ if (resourceVersion != null)
+ {
+ resourceName = resourceId.substring(start,lastSlash);
+ }
+ else
+ {
+ //no resource version, assume the remaining to be resource name
+ resourceName = resourceId.substring(start);
+ }
+ }
+ }
+ }
+
+ //Check libraryName and resourceName
+ if (resourceName == null)
+ {
+ return null;
+ }
+ if (!ResourceValidationUtils.isValidResourceName(resourceName))
+ {
+ return null;
+ }
+
+ if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
+ libraryName, isAllowSlashesLibraryName()))
+ {
+ return null;
+ }
+
+ // If some variable is "" set it as null.
+ if (localePrefix != null && localePrefix.length() == 0)
+ {
+ localePrefix = null;
+ }
+ if (libraryName != null && libraryName.length() == 0)
+ {
+ libraryName = null;
+ }
+ if (libraryVersion != null && libraryVersion.length() == 0)
+ {
+ libraryVersion = null;
+ }
+ if (resourceName != null && resourceName.length() == 0)
+ {
+ resourceName = null;
+ }
+ if (resourceVersion != null && resourceVersion.length() == 0)
+ {
+ resourceVersion = null;
+ }
+
+ resourceMeta = resourceLoader.createResourceMeta(
+ localePrefix, libraryName, libraryVersion, resourceName, resourceVersion, contractName);
+
+ if (resourceMeta != null &&
+ !resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ //}
+ return resourceMeta;
+ }
+
+ protected ResourceMeta deriveViewResourceMeta(FacesContext context, ResourceLoader resourceLoader,
+ String resourceName, String localePrefix)
+ {
+ ResourceMeta resourceMeta = null;
+ String resourceVersion = null;
+
+ //1. Try to locate resource in a localized path
+ if (localePrefix != null)
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(localePrefix + '/'+ resourceName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceMeta = resourceLoader.createResourceMeta(localePrefix, null, null,
+ resourceName, resourceVersion);
+ }
+
+ if (resourceMeta != null)
+ {
+ if (!resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ }
+ }
+
+ //2. Try to localize resource in a non localized path
+ if (resourceMeta == null)
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(resourceName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceMeta = resourceLoader.createResourceMeta(null, null, null,
+ resourceName, resourceVersion);
+ }
+
+ if (resourceMeta != null)
+ {
+ if (!resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ }
+ }
+
+ return resourceMeta;
+ }
+
+ protected ResourceMeta deriveViewResourceMeta(FacesContext context, ContractResourceLoader resourceLoader,
+ String resourceName, String localePrefix, String contractName)
+ {
+ ResourceMeta resourceMeta = null;
+ String resourceVersion = null;
+
+ //1. Try to locate resource in a localized path
+ if (localePrefix != null)
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(localePrefix + '/'+ resourceName, contractName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceMeta = resourceLoader.createResourceMeta(localePrefix, null, null,
+ resourceName, resourceVersion, contractName);
+ }
+
+ if (resourceMeta != null)
+ {
+ if (!resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ }
+ }
+
+ //2. Try to localize resource in a non localized path
+ if (resourceMeta == null)
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(resourceName, contractName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceMeta = resourceLoader.createResourceMeta(null, null, null,
+ resourceName, resourceVersion, contractName);
+ }
+
+ if (resourceMeta != null)
+ {
+ if (!resourceLoader.resourceExists(resourceMeta))
+ {
+ resourceMeta = null;
+ }
+ }
+ }
+
+ return resourceMeta;
+ }
+
+ @Override
+ public Resource createViewResource(FacesContext context, String resourceName)
+ {
+ // There are some special points to remember for a view resource in comparison
+ // with a normal resource:
+ //
+ // - A view resource never has an associated library name
+ // (this was done to keep simplicity).
+ // - A view resource can be inside a resource library contract.
+ // - A view resource could be internationalized in the same way a normal resource.
+ // - A view resource can be created from the webapp root folder,
+ // a normal resource cannot.
+ // - A view resource cannot be created from /resources or META-INF/resources.
+ //
+ // For example, a valid resourceId for a view resource is like this:
+ //
+ // [localePrefix/]resourceName[/resourceVersion]
+ //
+ // but the resource loader can ignore localePrefix or resourceVersion, like
+ // for example the webapp root folder.
+ //
+ // When createViewResource() is called, the view must be used to derive
+ // the localePrefix and facesContext must be used to get the available contracts.
+
+ Resource resource = null;
+
+ if (resourceName == null)
+ {
+ throw new NullPointerException();
+ }
+ if (resourceName.charAt(0) == '/')
+ {
+ // If resourceName starts with '/', remove that character because it
+ // does not have any meaning (with and without should point to the
+ // same resource).
+ resourceName = resourceName.substring(1);
+ }
+
+ // Later in deriveResourceMeta the resourceId is decomposed and
+ // its elements validated properly.
+ if (!ResourceValidationUtils.isValidViewResource(resourceName))
+ {
+ return null;
+ }
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ 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);
+
+ // Check cache:
+ //
+ // Contracts are on top of everything, because it is a concept that defines
+ // resources in a application scope concept. It means all resources in
+ // /resources or /META-INF/resources can be overriden using a contract. Note
+ // it also means resources under /META-INF/flows can also be overriden using
+ // a contract.
+ if (contractPreferred != null)
+ {
+ if (getResourceLoaderCache().containsViewResource(
+ resourceName, contentType, localePrefix, contractPreferred))
+ {
+ contractSelected = contractPreferred;
+ found = true;
+ }
+ }
+ if (!found && !contracts.isEmpty())
+ {
+ // Try to get resource but try with a contract name
+ for (String contract : contracts)
+ {
+ if (getResourceLoaderCache().containsViewResource(
+ resourceName, contentType, localePrefix, contract))
+ {
+ contractSelected = contract;
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ // Try to get resource without contract name
+ found = getResourceLoaderCache().containsViewResource(
+ resourceName, contentType, localePrefix);
+ }
+
+
+ if(found)
+ {
+ ResourceValue resourceValue = contractSelected != null ?
+ getResourceLoaderCache().getViewResource(resourceName,
+ contentType, localePrefix, contractSelected) :
+ getResourceLoaderCache().getViewResource(resourceName,
+ contentType, localePrefix);
+
+ resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
+ getResourceHandlerSupport(), contentType);
+ }
+ else
+ {
+ boolean resolved = false;
+ if (contractPreferred != null)
+ {
+ for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveViewResourceMeta(
+ facesContext, loader, resourceName, localePrefix, contractPreferred);
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putViewResource(
+ resourceName, contentType, localePrefix, contractPreferred, resourceMeta, loader);
+
+ resolved = true;
+ break;
+ }
+ }
+ }
+ if (!resolved && !contracts.isEmpty())
+ {
+ for (ContractResourceLoader loader :
+ getResourceHandlerSupport().getContractResourceLoaders())
+ {
+ for (String contract : contracts)
+ {
+ ResourceMeta resourceMeta = deriveViewResourceMeta(
+ facesContext, loader, resourceName, localePrefix, contract);
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(resourceMeta, loader,
+ getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putViewResource(
+ resourceName, contentType, localePrefix, contract, resourceMeta, loader);
+
+ resolved = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!resolved)
+ {
+ // "... Considering the web app root ..."
+
+ // "... Considering faces flows (at the locations specified in the spec prose document section
+ // Faces Flows in the Using JSF in Web Applications chapter) ..."
+ for (ResourceLoader loader : getResourceHandlerSupport().getViewResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveViewResourceMeta(
+ facesContext, loader, resourceName, localePrefix);
+
+ if (resourceMeta != null)
+ {
+ resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
+
+ // cache it
+ getResourceLoaderCache().putViewResource(
+ resourceName, contentType, localePrefix, resourceMeta, loader);
+ break;
+ }
+ }
+ }
+ }
+ return resource;
+ }
+
}
Copied: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_LocaleUtils.java (from r1470662, myfaces/core/trunk/api/src/main/java/javax/faces/component/_LocaleUtils.java)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_LocaleUtils.java?p2=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_LocaleUtils.java&p1=myfaces/core/trunk/api/src/main/java/javax/faces/component/_LocaleUtils.java&r1=1470662&r2=1485917&rev=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_LocaleUtils.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_LocaleUtils.java Fri May 24 01:27:31 2013
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package javax.faces.component;
+package org.apache.myfaces.application;
import java.util.ArrayList;
import java.util.Arrays;
@@ -143,6 +143,64 @@ class _LocaleUtils
}
}
}
+
+ /**
+ * Same as toLocale(), but return null when it cannot derive a valid Locale object.
+ *
+ * @param str
+ * @return
+ */
+ public static Locale deriveLocale(String str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ int len = str.length();
+ if (len != 2 && len != 5 && len < 7)
+ {
+ return null;
+ }
+ char ch0 = str.charAt(0);
+ char ch1 = str.charAt(1);
+ if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z')
+ {
+ return null;
+ }
+ if (len == 2)
+ {
+ return new Locale(str, "");
+ }
+ else
+ {
+ if (str.charAt(2) != '_')
+ {
+ return null;
+ }
+ char ch3 = str.charAt(3);
+ if (ch3 == '_')
+ {
+ return new Locale(str.substring(0, 2), "", str.substring(4));
+ }
+ char ch4 = str.charAt(4);
+ if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z')
+ {
+ return null;
+ }
+ if (len == 5)
+ {
+ return new Locale(str.substring(0, 2), str.substring(3, 5));
+ }
+ else
+ {
+ if (str.charAt(5) != '_')
+ {
+ return null;
+ }
+ return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
+ }
+ }
+ }
//-----------------------------------------------------------------------
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Fri May 24 01:27:31 2013
@@ -75,6 +75,7 @@ import org.apache.myfaces.config.annotat
import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
import org.apache.myfaces.config.element.Behavior;
import org.apache.myfaces.config.element.ClientBehaviorRenderer;
+import org.apache.myfaces.config.element.ContractMapping;
import org.apache.myfaces.config.element.FaceletsProcessing;
import org.apache.myfaces.config.element.FacesConfig;
import org.apache.myfaces.config.element.FacesConfigData;
@@ -102,10 +103,13 @@ import org.apache.myfaces.shared.config.
import org.apache.myfaces.shared.util.ClassUtils;
import org.apache.myfaces.shared.util.LocaleUtils;
import org.apache.myfaces.shared.util.StateUtils;
+import org.apache.myfaces.shared.util.StringUtils;
import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
import org.apache.myfaces.spi.FacesConfigurationMerger;
import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
+import org.apache.myfaces.spi.ResourceLibraryContractsProvider;
+import org.apache.myfaces.spi.ResourceLibraryContractsProviderFactory;
import org.apache.myfaces.util.ContainerUtils;
import org.apache.myfaces.util.ExternalSpecifications;
import org.apache.myfaces.view.ViewDeclarationLanguageFactoryImpl;
@@ -697,6 +701,13 @@ public class FacesConfigurator
dispenser.getVariableResolverIterator(),
new VariableResolverImpl()));
}
+
+ for (ContractMapping mapping : dispenser.getResourceLibraryContractMappings())
+ {
+ String urlPattern = mapping.getUrlPattern();
+ String[] contracts = StringUtils.trim(StringUtils.splitShortString(mapping.getContracts(), ' '));
+ runtimeConfig.addContractMapping(urlPattern, contracts);
+ }
}
/**
@@ -861,6 +872,57 @@ public class FacesConfigurator
{
runtimeConfig.addFaceletProcessingConfiguration(faceletsProcessing.getFileExtension(), faceletsProcessing);
}
+
+ ResourceLibraryContractsProvider rlcp = ResourceLibraryContractsProviderFactory.
+ getFacesConfigResourceProviderFactory(_externalContext).
+ createResourceLibraryContractsProvider(_externalContext);
+
+ try
+ {
+ // JSF 2.2 section 11.4.2.1 scan for available resource library contracts
+ // and store the result in a internal data structure, so it can be used
+ // later in ViewDeclarationLanguage.calculateResourceLibraryContracts(
+ // FacesContext context, String viewId)
+ runtimeConfig.setExternalContextResourceLibraryContracts(
+ rlcp.getExternalContextResourceLibraryContracts(_externalContext));
+ runtimeConfig.setClassLoaderResourceLibraryContracts(
+ rlcp.getClassloaderResourceLibraryContracts(_externalContext));
+ }
+ catch(Exception e)
+ {
+ if (log.isLoggable(Level.SEVERE))
+ {
+ log.log(Level.SEVERE,
+ "An error was found when scanning for resource library contracts", e);
+ }
+ }
+
+
+ // JSF 2.2 section 11.4.2.1 check all contracts are loaded
+ if (log.isLoggable(Level.INFO))
+ {
+ for (List<String> list : runtimeConfig.getContractMappings().values())
+ {
+ for (String contract : list)
+ {
+ if (!runtimeConfig.getResourceLibraryContracts().contains(contract))
+ {
+ log.log(Level.INFO,
+ "Resource Library Contract "+ contract + " was not found while scanning for "
+ + "available contracts.");
+ }
+ }
+ }
+ }
+
+ // JSF 2.2 section 11.4.2.1 if no contractMappings set, all available contracts applies
+ // to all views.
+ if (runtimeConfig.getContractMappings().isEmpty())
+ {
+ String[] contracts = runtimeConfig.getResourceLibraryContracts().toArray(
+ new String[runtimeConfig.getResourceLibraryContracts().size()]);
+ runtimeConfig.addContractMapping("*", contracts);
+ }
}
private void removePurgedBeansFromSessionAndApplication(RuntimeConfig runtimeConfig)
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java Fri May 24 01:27:31 2013
@@ -23,8 +23,10 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -88,6 +90,20 @@ public class RuntimeConfig
private final Map<String, FaceletsProcessing> _faceletsProcessingByFileExtension =
new HashMap<String, FaceletsProcessing>();
+
+ /**
+ * JSF 2.2 section 11.4.2.1.
+ *
+ * Scanning for all available contracts is necessary because the spec says
+ * "... if the information from the application configuration resources refers
+ * to a contract that is not available to the application, an informative error
+ * message must be logged. ..."
+ */
+ private Set<String> _externalContextResourceLibraryContracts = new HashSet<String>();
+ private Set<String> _classLoaderResourceLibraryContracts = new HashSet<String>();
+ private Set<String> _resourceLibraryContracts = new HashSet<String>();
+
+ private Map<String, List<String>> _contractMappings = new HashMap<String, List<String>>();
public static RuntimeConfig getCurrentInstance(ExternalContext externalContext)
{
@@ -109,6 +125,9 @@ public class RuntimeConfig
_managedBeans.clear();
_navigationRulesChanged = false;
_converterClassNameToConfigurationMap.clear();
+ _externalContextResourceLibraryContracts.clear();
+ _classLoaderResourceLibraryContracts.clear();
+ _resourceLibraryContracts.clear();
}
/**
@@ -378,4 +397,84 @@ public class RuntimeConfig
{
return _faceletsProcessingByFileExtension.values();
}
+
+ /**
+ * @return the _externalContextResourceLibraryContracts
+ */
+ public Set<String> getExternalContextResourceLibraryContracts()
+ {
+ return _externalContextResourceLibraryContracts;
+ }
+
+ /**
+ * @param externalContextResourceLibraryContracts the _externalContextResourceLibraryContracts to set
+ */
+ public void setExternalContextResourceLibraryContracts(Set<String> externalContextResourceLibraryContracts)
+ {
+ this._externalContextResourceLibraryContracts = externalContextResourceLibraryContracts;
+ this._resourceLibraryContracts.clear();
+ this._resourceLibraryContracts.addAll(this._externalContextResourceLibraryContracts);
+ this._resourceLibraryContracts.addAll(this._classLoaderResourceLibraryContracts);
+ }
+
+ /**
+ * @return the _classLoaderResourceLibraryContracts
+ */
+ public Set<String> getClassLoaderResourceLibraryContracts()
+ {
+ return _classLoaderResourceLibraryContracts;
+ }
+
+ /**
+ * @param classLoaderResourceLibraryContracts the _classLoaderResourceLibraryContracts to set
+ */
+ public void setClassLoaderResourceLibraryContracts(Set<String> classLoaderResourceLibraryContracts)
+ {
+ this._classLoaderResourceLibraryContracts = classLoaderResourceLibraryContracts;
+ this._resourceLibraryContracts.clear();
+ this._resourceLibraryContracts.addAll(this._externalContextResourceLibraryContracts);
+ this._resourceLibraryContracts.addAll(this._classLoaderResourceLibraryContracts);
+ }
+
+ /**
+ * @return the _resourceLibraryContracts
+ */
+ public Set<String> getResourceLibraryContracts()
+ {
+ return _resourceLibraryContracts;
+ }
+
+ /**
+ * @return the _contractMappings
+ */
+ public Map<String, List<String>> getContractMappings()
+ {
+ return _contractMappings;
+ }
+
+ public void addContractMapping(String urlPattern, String[] contracts)
+ {
+ List<String> contractsList = _contractMappings.get(urlPattern);
+ if (contractsList == null)
+ {
+ contractsList = new ArrayList<String>();
+ _contractMappings.put(urlPattern, contractsList);
+ }
+ for (String contract : contracts)
+ {
+ contractsList.add(contract);
+ }
+ }
+
+ public void addContractMapping(String urlPattern, String contract)
+ {
+ List<String> contractsList = _contractMappings.get(urlPattern);
+ if (contractsList == null)
+ {
+ contractsList = new ArrayList<String>();
+ _contractMappings.put(urlPattern, contractsList);
+ }
+ contractsList.add(contract);
+ }
+
}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java?rev=1485917&r1=1485916&r2=1485917&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java Fri May 24 01:27:31 2013
@@ -18,7 +18,10 @@
*/
package org.apache.myfaces.context.servlet;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.el.ELContext;
@@ -64,6 +67,8 @@ public abstract class FacesContextImplBa
protected boolean _released = false;
private ApplicationFactory _applicationFactory = null;
+
+ private List<String> _resourceLibraryContracts;
/**
* Base constructor.
@@ -308,6 +313,40 @@ public abstract class FacesContextImplBa
return _cachedRenderKit;
}
+
+ @Override
+ public List<String> getResourceLibraryContracts()
+ {
+ assertNotReleased();
+
+ if (_resourceLibraryContracts == null)
+ {
+ return Collections.emptyList();
+ }
+ else
+ {
+ return _resourceLibraryContracts;
+ }
+ }
+
+ @Override
+ public void setResourceLibraryContracts(List<String> contracts)
+ {
+ assertNotReleased();
+
+ if (contracts == null)
+ {
+ _resourceLibraryContracts = null;
+ }
+ else if (contracts.isEmpty())
+ {
+ _resourceLibraryContracts = null;
+ }
+ else
+ {
+ _resourceLibraryContracts = new ArrayList<String>(contracts);
+ }
+ }
/**
* has to be thrown in many of the methods if the method is called after the instance has been released!