IsResourceRequest() does look like a good hook to handle the multi-part stream, without any side effects of the lifecycle interfering, since it is before the lifecycle:
Although this does seem like a nice hook for running as soon as possible, since it comes before Lifecycle.execute even happens:
FacesServlet.service
{
// Acquire the FacesContext instance for this request
FacesContext context = facesContextFactory.getFacesContext
(servletConfig.getServletContext(), request, response, lifecycle);
// Execute the request processing lifecycle for this request
try {
ResourceHandler handler =
context.getApplication().getResourceHandler();
if (handler.isResourceRequest(context))
{
handler.handleResourceRequest(context);
}
else
{
lifecycle.execute(context);
lifecycle.render(context);
}
But in case there is a problem that we're processing things outside/before the lifecycle, there might be a more surgical alteration we could try. If we change AutoUpdateCallbackPartialViewContext and RequestContext so that the DefaultRequestContext instance is lazily set, instead of in AutoUpdateCallbackPartialViewContext's constructor, so that AutoUpdateCallbackPartialViewContext.isAjaxRequest() is not called until later, then maybe that will solve this issue. All the methods in these classes seem to only be needed in ApplyRequestValuesPhase and after. And FileEntryPhaseListener is a little touchy in needing some of this stuff to not be invoked yet in RestoreViewPhase.
Multipart POST decoding via commons-fileupload is now being done in FileEntryResourceHandler.isResourceRequest(). This is an abuse of the isResourceRequest() method, but allows the InputStream to be decoded.
There is still redundant code in both FileEntryResourceHandler and FileEntryPhaseListener, so both of these classes are badly in need of some refactoring to remove dead and redundant code.