Class ResourceHandler
- java.lang.Object
-
- jakarta.faces.application.ResourceHandler
-
- Direct Known Subclasses:
ResourceHandlerWrapper
public abstract class ResourceHandler extends Object
ResourceHandler is the run-time API by which
UIComponentandRendererinstances, and theViewDeclarationLanguagecan referenceResourceinstances. An implementation of this class must be thread-safe.Packaging Resources
ResourceHandler defines a path based packaging convention for resources. The default implementation of
ResourceHandlermust support packaging resources in the classpath or in the web application root. See section 2.6.1 "Packaging Resources" of the Jakarta Faces Specification Document for the normative specification of packaging resources.Briefly, The default implementation must support packaging resources in the web application root under the path
resources/<resourceIdentifier>relative to the web app root. "resources" is the default location, but this location can be changed by the value of the
WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME<context-param>.For the default implementation, resources packaged in the classpath must reside under the JAR entry name
META-INF/resources/<resourceIdentifier>In the case of Faces Flows packaged within jar files, resources packaged in the classpath must reside under the jar entry name
META-INF/flows/<resourceIdentifier><resourceIdentifier>consists of several segments, specified as follows.[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]None of the segments in the resourceIdentifier may be relative paths, such as ‘../otherLibraryName’. The implementation is not required to support the
libraryVersionandresourceVersionsegments for the JAR packaging case.Note that resourceName is the only required segment.
Encoding Resources
During the handling of view requests, the Jakarta Server Face run-time may be called upon to encode a resource in such a way as to instruct the user-agent to make a subsequent resource request. This behavior is orchestrated by one of the resource renderers (
ScriptRenderer,StylesheetRenderer,ImageRenderer), which all callResource.getRequestPath()to obtain the encoded URI for the resource. SeeResource.getRequestPath()and the Standard HTML RenderKit specification for the complete specification.This usage of resources does not apply for resources that correspond to VDL resources.
Decoding Resources
During the handling of resource requests, the Jakarta Faces run-time will be called upon to decode a resource in such a way as to serve up the bytes of the resource to the user-agent. This behavior is orchestrated by
handleResourceRequest(jakarta.faces.context.FacesContext), which callsResource.getInputStream()to obtain bytes of the resource. SeehandleResourceRequest(jakarta.faces.context.FacesContext)for the complete specification.This usage of resources does not apply for resources that correspond to VDL resources.
- Since:
- 2.0
-
-
Field Summary
Fields Modifier and Type Field Description static StringFACES_SCRIPT_LIBRARY_NAMELibrary name of Jakarta Faces script resource.static StringFACES_SCRIPT_RESOURCE_NAMEResource name of Jakarta Faces script resource.static StringJSF_SCRIPT_LIBRARY_NAMEDeprecated, for removal: This API element is subject to removal in a future version.UseFACES_SCRIPT_LIBRARY_NAMEinstead.static StringJSF_SCRIPT_RESOURCE_NAMEDeprecated, for removal: This API element is subject to removal in a future version.UseFACES_SCRIPT_RESOURCE_NAMEinstead.static StringLOCALE_PREFIXThe name of a key within the application message bundle named by the return fromApplication.getMessageBundle()whose value is the locale prefix used to find a packaged resource to return fromcreateResource(java.lang.String)(or one of its variants).static StringRESOURCE_CONTRACT_XMLThis file must be located inMETA-INF/contracts/<contractName>/in a jar file that contains a resource library contract, where<contractName>is the name of the contract.static StringRESOURCE_EXCLUDES_DEFAULT_VALUEThe default value for theRESOURCE_EXCLUDES_PARAM_NAMEinit param.static StringRESOURCE_EXCLUDES_PARAM_NAMETheServletContextinit parameter consulted by thehandleResourceRequest(jakarta.faces.context.FacesContext)to tell which kinds of resources must never be served up in response to a resource request.static StringRESOURCE_IDENTIFIERResource.getRequestPath()returns the value of this constant as the prefix of the URI.static StringWEBAPP_CONTRACTS_DIRECTORY_PARAM_NAMEIf a<context-param>with the param name equal to the value ofWEBAPP_CONTRACTS_DIRECTORY_PARAM_NAMEexists, the runtime must interpret its value as a path, relative to the web app root, where resource library contracts are to be located.static StringWEBAPP_RESOURCES_DIRECTORY_PARAM_NAMEIf a<context-param>with the param name equal to the value ofWEBAPP_RESOURCES_DIRECTORY_PARAM_NAMEexists, the runtime must interpret its value as a path, relative to the web app root, where resources are to be located.
-
Constructor Summary
Constructors Constructor Description ResourceHandler()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract ResourcecreateResource(String resourceName)Create an instance ofViewResourcegiven the argumentresourceName.abstract ResourcecreateResource(String resourceName, String libraryOrContractName)Create an instance ofResourcewith a resourceName given by the value of the argumentresourceNamethat is a member of the library named by the argumentlibraryName.abstract ResourcecreateResource(String resourceName, String libraryName, String contentType)Create an instance ofResourcewith a resourceName given by the value of the argumentresourceNamethat is a member of the library named by the argumentlibraryNamethat claims to have the content-type given by the argumentcontent-type.ResourcecreateResourceFromId(String resourceId)Create an instance ofResourcegiven the argumentresourceId.ViewResourcecreateViewResource(FacesContext context, String resourceName)Create an instance ofResourcegiven the argumentresourceName, which may contain "/" characters.abstract StringgetRendererTypeForResourceName(String resourceName)Return therenderer-typefor aRendererthat is capable of rendering this resource.Stream<String>getViewResources(FacesContext facesContext, String path, int maxDepth, ResourceVisitOption... options)Return aStreampossibly lazily populated by walking the resource tree rooted at a given initial path.Stream<String>getViewResources(FacesContext facesContext, String path, ResourceVisitOption... options)Return aStreampossibly lazily populated by walking the resource tree rooted at a given initial path.abstract voidhandleResourceRequest(FacesContext context)This method specifies the contract for satisfying resource requests.booleanisResourceRendered(FacesContext context, String resourceName, String libraryName)Returns whether the resource as identified by given resource and library name has been rendered.abstract booleanisResourceRequest(FacesContext context)Returntrueif the current request is a resource request.booleanisResourceURL(String url)Returntrueif the argumenturlcontains the string given by the value of the constantRESOURCE_IDENTIFIER, false otherwise.abstract booleanlibraryExists(String libraryName)Returntrueif the resource library named by the argumentlibraryNamecan be found.voidmarkResourceRendered(FacesContext context, String resourceName, String libraryName)Mark the resource as identified by given resource and library name as rendered.
-
-
-
Field Detail
-
RESOURCE_IDENTIFIER
public static final String RESOURCE_IDENTIFIER
Resource.getRequestPath()returns the value of this constant as the prefix of the URI.handleResourceRequest(jakarta.faces.context.FacesContext)looks for the value of this constant within the request URI to determine if the request is a resource request or a view request.- See Also:
- Constant Field Values
-
JSF_SCRIPT_RESOURCE_NAME
@Deprecated(since="4.0", forRemoval=true) public static final String JSF_SCRIPT_RESOURCE_NAME
Deprecated, for removal: This API element is subject to removal in a future version.UseFACES_SCRIPT_RESOURCE_NAMEinstead.Resource name of Jakarta Faces script resource.
- Since:
- 2.3
- See Also:
- Constant Field Values
-
FACES_SCRIPT_RESOURCE_NAME
public static final String FACES_SCRIPT_RESOURCE_NAME
Resource name of Jakarta Faces script resource.
- Since:
- 2.3
- See Also:
- Constant Field Values
-
JSF_SCRIPT_LIBRARY_NAME
@Deprecated(since="4.0", forRemoval=true) public static final String JSF_SCRIPT_LIBRARY_NAME
Deprecated, for removal: This API element is subject to removal in a future version.UseFACES_SCRIPT_LIBRARY_NAMEinstead.Library name of Jakarta Faces script resource.
- Since:
- 2.3
- See Also:
- Constant Field Values
-
FACES_SCRIPT_LIBRARY_NAME
public static final String FACES_SCRIPT_LIBRARY_NAME
Library name of Jakarta Faces script resource.
- Since:
- 2.3
- See Also:
- Constant Field Values
-
RESOURCE_CONTRACT_XML
public static final String RESOURCE_CONTRACT_XML
This file must be located in
META-INF/contracts/<contractName>/in a jar file that contains a resource library contract, where<contractName>is the name of the contract. If the jar file contains multiple contracts, the marker file must be present in each one. See “constant field values” for the name of the file that must be placed at that location.- Since:
- 2.2
- See Also:
- Constant Field Values
-
WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME
public static final String WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME
If a
<context-param>with the param name equal to the value ofWEBAPP_RESOURCES_DIRECTORY_PARAM_NAMEexists, the runtime must interpret its value as a path, relative to the web app root, where resources are to be located. This param value must not start with a "/", though it may contain "/" characters. If no such<context-param>exists, or its value is invalid, the value "resources", without the quotes, must be used by the runtime as the value.- Since:
- 2.2
- See Also:
- Constant Field Values
-
WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME
public static final String WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME
If a
<context-param>with the param name equal to the value ofWEBAPP_CONTRACTS_DIRECTORY_PARAM_NAMEexists, the runtime must interpret its value as a path, relative to the web app root, where resource library contracts are to be located. This param value must not start with a "/", though it may contain "/" characters. If no such<context-param>exists, or its value is invalid, the value "contracts", without the quotes, must be used by the runtime as the value.- Since:
- 2.2
- See Also:
- Constant Field Values
-
LOCALE_PREFIX
public static final String LOCALE_PREFIX
The name of a key within the application message bundle named by the return from
Application.getMessageBundle()whose value is the locale prefix used to find a packaged resource to return fromcreateResource(java.lang.String)(or one of its variants).- See Also:
- Constant Field Values
-
RESOURCE_EXCLUDES_PARAM_NAME
public static final String RESOURCE_EXCLUDES_PARAM_NAME
The
ServletContextinit parameter consulted by thehandleResourceRequest(jakarta.faces.context.FacesContext)to tell which kinds of resources must never be served up in response to a resource request. The value of this parameter is a single space separated list of file extensions, including the leading '.' character (without the quotes). If not specified, the default value given in the value of theRESOURCE_EXCLUDES_DEFAULT_VALUEconstant is used. If manually specified, the given value entirely overrides the default one and does not supplement it.- See Also:
- Constant Field Values
-
RESOURCE_EXCLUDES_DEFAULT_VALUE
public static final String RESOURCE_EXCLUDES_DEFAULT_VALUE
The default value for the
RESOURCE_EXCLUDES_PARAM_NAMEinit param.- See Also:
- Constant Field Values
-
-
Method Detail
-
createResource
public abstract Resource createResource(String resourceName)
Create an instance of
ViewResourcegiven the argumentresourceName. The content-type of the resource is derived by passing the resourceName toExternalContext.getMimeType(java.lang.String)The algorithm specified in section 2.6.1.4 "Libraries of Localized and Versioned Resources" of the Jakarta Faces Specification Document must be executed to create the
Resource. New requirements were introduced in version 2.2 of the specification. For historical reasons, this method operate correctly when the argumentresourceNameis of the formlibraryName/resourceName, even whenresourceNamecontains '/' characters.- Parameters:
resourceName- the name of the resource.- Returns:
- a newly created
Resourceinstance, suitable for use in encoding or decoding the named resource. - Throws:
NullPointerException- ifresourceNameisnull.
-
createViewResource
public ViewResource createViewResource(FacesContext context, String resourceName)
Create an instance of
Resourcegiven the argumentresourceName, which may contain "/" characters. TheViewDeclarationLanguagecalls this method when it needs to load a view from a persistent store, such as a filesystem. This method is functionality equivalent tocreateResource(java.lang.String), but all callsites that need to load VDL views must use this method so that classes that want to decorate theResourceHandlerin order to only affect the loading of views may do so without affecting the processing of other kinds of resources, such as scripts and stylesheets. AFacesContextmust be present before calling this method. To preserve compatibility with prior revisions of the specification, a default implementation must be provided that callscreateResource(java.lang.String).The default implementation must look for the resource in the following places, in this order.
-
Considering resource library contracts (at the locations specified in the Jakarta Faces Specification Document section 2.7 "Resource Library Contracts").
-
Considering the web app root.
-
Considering faces flows (at the locations specified in the Jakarta Faces Specification Document section 11.3.3 "Faces Flows").
Call
FacesContext.getResourceLibraryContracts(). If the result is non-nulland not empty, for each value in the list, treat the value as the name of a resource library contract. If the argumentresoureNameexists as a resource in the resource library contract, return it. Otherwise, return the resource (not in the resource library contract), if found. Otherwise, returnnull.- Parameters:
context- theFacesContextfor this request.resourceName- the name of the resource to be interpreted as a view by theViewDeclarationLanguage.- Returns:
- a newly created
ViewResourceinstance, suitable for use by theViewDeclarationLanguage. - Throws:
NullPointerException- ifresourceNameisnull.- Since:
- 2.2
-
-
getViewResources
public Stream<String> getViewResources(FacesContext facesContext, String path, int maxDepth, ResourceVisitOption... options)
Return a
Streampossibly lazily populated by walking the resource tree rooted at a given initial path. The resource tree is traversed breadth-first, the elements in the stream are view resource names that would yield aViewResourcewhen passed intocreateViewResource(jakarta.faces.context.FacesContext, java.lang.String)as theresourceNameparameter.The
maxDepthparameter is the maximum depth of directory levels to visit beyond the initial path, which is always visited. The value is relative to the root (/), not to the given initial path. E.g. givenmaxDepth=3and initial path/foo/, visiting will proceed up to/foo/bar/, where/counts as depth1,/foo/as depth2and/foo/bar/as depth3. A value lower or equal to the depth of the initial path means that only the initial path is visited. A value ofMAX_VALUEmay be used to indicate that all levels should be visited.- Parameters:
facesContext- TheFacesContextfor this request.path- The initial path from which to start looking for view resourcesmaxDepth- The absolute maximum depth of nested directories to visit counted from the root (/).options- The options to influence the traversal. SeeResourceVisitOptionfor details on those.- Returns:
- the
Streamof view resource names - Since:
- 2.3
-
getViewResources
public Stream<String> getViewResources(FacesContext facesContext, String path, ResourceVisitOption... options)
Return a
Streampossibly lazily populated by walking the resource tree rooted at a given initial path. The resource tree is traversed breadth-first, the elements in the stream are view resource names that would yield aViewResourcewhen passed intocreateViewResource(jakarta.faces.context.FacesContext, java.lang.String)as theresourceNameparameter.This method works as if invoking it were equivalent to evaluating the expression:
Put differently, it visits all levels of the resource tree.getViewResources(facesContext, start, Integer.MAX_VALUE, options)
- Parameters:
facesContext- TheFacesContextfor this request.path- The initial path from which to start looking for view resourcesoptions- The options to influence the traversal. SeeResourceVisitOptionfor details on those.- Returns:
- the
Streamof view resource names - Since:
- 2.3
-
createResourceFromId
public Resource createResourceFromId(String resourceId)
Create an instance of
Resourcegiven the argumentresourceId. The content-type of the resource is derived by passing the resourceName toExternalContext.getMimeType(java.lang.String)The resource must be identified according to the specification in section 2.6.1.3 "Resource Identifiers" of the Jakarta Faces Specification Document. New requirements were introduced in version 2.2 of the specification.
- Parameters:
resourceId- the resource identifier of the resource.- Returns:
- a newly created
Resourceinstance, suitable for use in encoding or decoding the named resource. - Throws:
NullPointerException- ifresourceIdisnull.- Since:
- 2.2
-
createResource
public abstract Resource createResource(String resourceName, String libraryOrContractName)
Create an instance of
Resourcewith a resourceName given by the value of the argumentresourceNamethat is a member of the library named by the argumentlibraryName. The content-type of the resource is derived by passing the resourceName toExternalContext.getMimeType(java.lang.String).The algorithm specified in section 2.6.1.4 "Libraries of Localized and Versioned Resources" of the Jakarta Faces Specification Document must be executed to create the
Resource. New requirements were introduced in version 2.2 of the specification.- Parameters:
resourceName- the name of the resource.libraryOrContractName- the name of the library (or contract) in which this resource resides, may benull. If there is a conflict between the name of a resource library and a resource library contract, the resource library takes precedence. May not include relative paths, such as "../".- Returns:
- a newly created
Resourceinstance, suitable for use in encoding or decoding the named resource. - Throws:
NullPointerException- ifresourceNameisnull
-
createResource
public abstract Resource createResource(String resourceName, String libraryName, String contentType)
Create an instance of
Resourcewith a resourceName given by the value of the argumentresourceNamethat is a member of the library named by the argumentlibraryNamethat claims to have the content-type given by the argumentcontent-type.The algorithm specified in section 2.6.1.4 "Libraries of Localized and Versioned Resources" of the Jakarta Faces Specification Document must be executed to create the
Resource. New requirements were introduced in version 2.2 of the specification.- Parameters:
resourceName- the name of the resource.libraryName- the name of the library in which this resource resides, may benull. May not include relative paths, such as "../".contentType- the mime content that thisResourceinstance will return fromResource.getContentType(). If the value isnull, The content-type of the resource is derived by passing the resourceName toExternalContext.getMimeType(java.lang.String)- Returns:
- a newly created
Resourceinstance, suitable for use in encoding or decoding the named resource. - Throws:
NullPointerException- ifresourceNameisnull.
-
libraryExists
public abstract boolean libraryExists(String libraryName)
Return
trueif the resource library named by the argumentlibraryNamecan be found. If there is alocalePrefixfor this application, as defined inLOCALE_PREFIX, first look for the library with the prefix. If no such library is found, look for the library without the prefix. This allows developers to avoid duplication of files. For example, consider the case where the developer wants to have a resource library containing a localized image resource and a non-localized script resource. By checking both locations for the existence of the library, along with other spec changes in section 2.6.1.4 "Libraries of Localized and Versioned Resources" of the Jakarta Faces Specification Document, this scenario is enabled.- Parameters:
libraryName- the library name.- Returns:
trueif the library exists,falseotherwise.- Since:
- 2.0
-
handleResourceRequest
public abstract void handleResourceRequest(FacesContext context) throws IOException
This method specifies the contract for satisfying resource requests. This method is called from
FacesServlet.service(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse)after that method determines the current request is a resource request by callingisResourceRequest(jakarta.faces.context.FacesContext). Thus,handleResourceRequestmay assume that the current request is a resource request.The default implementation must implement an algorithm semantically identical to the following algorithm.
For discussion, in all cases when a status code is to be set, this spec talks only using the Jakarta Servlet API, but it is understood that in a portlet environment the appropriate equivalent API must be used.-
If the resourceIdentifier ends with any of the extensions listed in the value of the
RESOURCE_EXCLUDES_PARAM_NAMEinit parameter,HttpServletRequest.SC_NOT_FOUNDmust be passed toHttpServletResponse.setStatus(), thenhandleResourceRequestmust immediately return. -
Extract the resourceName from the resourceIdentifier by taking the substring of resourceIdentifier that starts at
and goes to the end of resourceIdentifier. If no resourceName can be extracted,RESOURCE_IDENTIFIER.length() + 1HttpServletRequest.SC_NOT_FOUNDmust be passed toHttpServletResponse.setStatus(), thenhandleResourceRequestmust immediately return. -
Extract the libraryName from the request by looking in the request parameter map for an entry under the key "ln", without the quotes. If found, use its value as the libraryName.
-
If resourceName and libraryName are present, call
createResource(String, String)to create theResource. If only resourceName is present, callcreateResource(String)to create theResource. If theResourcecannot be successfully created,HttpServletRequest.SC_NOT_FOUNDmust be passed toHttpServletResponse.setStatus(), thenhandleResourceRequestmust immediately return. -
Call
Resource.userAgentNeedsUpdate(jakarta.faces.context.FacesContext). If this method returns false,HttpServletRequest.SC_NOT_MODIFIEDmust be passed toHttpServletResponse.setStatus(), thenhandleResourceRequestmust immediately return. -
Pass the result of
Resource.getContentType()toHttpServletResponse.setContentType. -
Call
Resource.getResponseHeaders(). For each entry in thisMap, callHttpServletResponse.setHeader(), passing the key as the first argument and the value as the second argument. -
Call
Resource.getInputStream()and serve up the bytes of the resource to the response. -
Call
HttpServletResponse.setContentLength()passing the byte count of the resource. -
If an
IOExceptionis thrown during any of the previous steps, log a descriptive, localized message, including the resourceName and libraryName (if present). Then,HttpServletRequest.SC_NOT_FOUNDmust be passed toHttpServletResponse.setStatus(), thenhandleResourceRequestmust immediately return. -
In all cases in this method, any streams, channels, sockets, or any other IO resources must be closed before this method returns.
- Parameters:
context- theFacesContextfor this request- Throws:
IOException- when an I/O error occurs.
-
-
isResourceRequest
public abstract boolean isResourceRequest(FacesContext context)
Return
trueif the current request is a resource request. This method is called byFacesServlet.service(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse)to determine if this request is a view request or a resource request.- Parameters:
context- theFacesContextfor this request- Returns:
trueif the current request is a resource request,falseotherwise.
-
isResourceURL
public boolean isResourceURL(String url)
Return
trueif the argumenturlcontains the string given by the value of the constantRESOURCE_IDENTIFIER, false otherwise.- Parameters:
url- the url to inspect for the presence ofRESOURCE_IDENTIFIER.- Returns:
trueif this is a resource URL,falseotherwise.- Throws:
NullPointerException- if the argument url isnull.
-
getRendererTypeForResourceName
public abstract String getRendererTypeForResourceName(String resourceName)
Return the
renderer-typefor aRendererthat is capable of rendering this resource. The default implementation must return values according to the following table. If norenderer-typecan be determined,nullmust be returned.resource name to renderer-type mapping example resource name renderer-type mycomponent.js jakarta.faces.resource.Scriptmystyle.css jakarta.faces.resource.Stylesheet- Parameters:
resourceName- the resource name.- Returns:
- the renderer type.
-
markResourceRendered
public void markResourceRendered(FacesContext context, String resourceName, String libraryName)
Mark the resource as identified by given resource and library name as rendered. The default implementation must ensure that
isResourceRendered(FacesContext, String, String)will returntruewhen the resource has already been rendered during the render response phase of the current view.- Parameters:
context- TheFacesContextfor this request.resourceName- The name of the resource.libraryName- The name of the library in which the resource resides, may benull.- Since:
- 2.3
-
isResourceRendered
public boolean isResourceRendered(FacesContext context, String resourceName, String libraryName)
Returns whether the resource as identified by given resource and library name has been rendered. The default implementation must during the render response phase of the current view return
truewhen the resource has been marked as rendered viamarkResourceRendered(FacesContext, String, String).- Parameters:
context- TheFacesContextfor this request.resourceName- The name of the resource.libraryName- The name of the library in which this resource resides, may benull.- Returns:
- Whether the resource as identified by given resource and library name has been rendered.
- Since:
- 2.3
-
-