use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.
the class NavigationHandlerImpl method handleNavigation.
@Override
public void handleNavigation(FacesContext facesContext, String fromAction, String outcome, String toFlowDocumentId) {
NavigationContext navigationContext = new NavigationContext();
NavigationCase navigationCase = null;
try {
navigationCase = getNavigationCommand(facesContext, navigationContext, fromAction, outcome, toFlowDocumentId);
} finally {
navigationContext.finish(facesContext);
}
if (navigationCase != null) {
if (log.isLoggable(Level.FINEST)) {
log.finest("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + " toViewId =" + navigationCase.getToViewId(facesContext) + " redirect=" + navigationCase.isRedirect());
}
boolean isViewActionProcessingBroadcastAndRequiresRedirect = false;
if (UIViewAction.isProcessingBroadcast(facesContext)) {
// f:viewAction tag always triggers a redirect to enforce execution of
// the lifecycle again. Note this requires enables flash scope
// keepMessages automatically, because a view action can add messages
// and these ones requires to be renderer afterwards.
facesContext.getExternalContext().getFlash().setKeepMessages(true);
String fromViewId = (facesContext.getViewRoot() == null) ? null : facesContext.getViewRoot().getViewId();
String toViewId = navigationCase.getToViewId(facesContext);
// lifecycle is not necessary.
if (fromViewId == null && toViewId != null) {
isViewActionProcessingBroadcastAndRequiresRedirect = true;
} else if (fromViewId != null && !fromViewId.equals(toViewId)) {
isViewActionProcessingBroadcastAndRequiresRedirect = true;
}
}
if (navigationCase.isRedirect() || isViewActionProcessingBroadcastAndRequiresRedirect) {
// Need to add the FlowHandler parameters here.
FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
List<Flow> activeFlows = FlowHandlerImpl.getActiveFlows(facesContext, flowHandler);
Flow currentFlow = flowHandler.getCurrentFlow(facesContext);
Flow targetFlow = calculateTargetFlow(facesContext, outcome, flowHandler, activeFlows, toFlowDocumentId);
Map<String, List<String>> navigationCaseParameters = navigationCase.getParameters();
// sourceFlow and targetFlow could both be null so need to have multiple checks here
if (currentFlow != targetFlow) {
// Ensure that at least one has a value and check for equality
if ((currentFlow != null && !currentFlow.equals(targetFlow)) || (targetFlow != null && !targetFlow.equals(currentFlow))) {
if (navigationCaseParameters == null) {
navigationCaseParameters = new HashMap<>(5, 1f);
}
// include the following entries:
if (currentFlow != null && targetFlow == null) {
// Set the TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME parameter
navigationCaseParameters.put(FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME, Arrays.asList(FlowHandler.NULL_FLOW));
// Set the FLOW_ID_REQUEST_PARAM_NAME
navigationCaseParameters.put(FlowHandler.FLOW_ID_REQUEST_PARAM_NAME, Arrays.asList(""));
} else {
// If current flow (sourceFlow) is null and new flow (targetFlow) is not null,
// include the following entries:
// If we make it this far we know the above statement is true due to the other
// logical checks we have hit to this point.
// Set the TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME parameter
navigationCaseParameters.put(FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME, Arrays.asList((toFlowDocumentId == null ? "" : toFlowDocumentId)));
// Set the FLOW_ID_REQUEST_PARAM_NAME
navigationCaseParameters.put(FlowHandler.FLOW_ID_REQUEST_PARAM_NAME, Arrays.asList(targetFlow.getId()));
}
}
}
ExternalContext externalContext = facesContext.getExternalContext();
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
String toViewId = navigationCase.getToViewId(facesContext);
String redirectPath = viewHandler.getRedirectURL(facesContext, toViewId, NavigationUtils.getEvaluatedNavigationParameters(facesContext, navigationCaseParameters), navigationCase.isIncludeViewParams());
// The spec doesn't say anything about how to handle redirect but it is
// better to apply the transition here where we have already calculated the
// route than add the parameters and delegate to
// FlowHandler.clientWindowTransition(facesContext)
applyFlowTransition(facesContext, navigationContext);
// Clear ViewMap if we are redirecting to other resource
UIViewRoot viewRoot = facesContext.getViewRoot();
if (viewRoot != null && !toViewId.equals(viewRoot.getViewId())) {
// call getViewMap(false) to prevent unnecessary map creation
Map<String, Object> viewMap = viewRoot.getViewMap(false);
if (viewMap != null) {
viewMap.clear();
}
}
// JSF 2.0 the javadoc of handleNavigation() says something like this
// "...If the view has changed after an application action, call
// PartialViewContext.setRenderAll(true)...". The effect is that ajax requests
// are included on navigation.
PartialViewContext partialViewContext = facesContext.getPartialViewContext();
String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
if (partialViewContext.isPartialRequest() && !partialViewContext.isRenderAll() && toViewId != null && !toViewId.equals(viewId)) {
partialViewContext.setRenderAll(true);
}
// Dispose view if the view has been marked as disposable by default action listener
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
if (processor != null && processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot())) {
processor.disposeView(facesContext, facesContext.getViewRoot());
}
// JSF 2.0 Spec call Flash.setRedirect(true) to notify Flash scope and take proper actions
externalContext.getFlash().setRedirect(true);
try {
externalContext.redirect(redirectPath);
facesContext.responseComplete();
} catch (IOException e) {
throw new FacesException(e.getMessage(), e);
}
} else {
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
// create new view
String newViewId = navigationCase.getToViewId(facesContext);
// JSF 2.0 the javadoc of handleNavigation() says something like this
// "...If the view has changed after an application action, call
// PartialViewContext.setRenderAll(true)...". The effect is that ajax requests
// are included on navigation.
PartialViewContext partialViewContext = facesContext.getPartialViewContext();
String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
if (partialViewContext.isPartialRequest() && !partialViewContext.isRenderAll() && newViewId != null && !newViewId.equals(viewId)) {
partialViewContext.setRenderAll(true);
}
if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getAttributes().containsKey(CALL_PRE_DISPOSE_VIEW)) {
try {
facesContext.getAttributes().put(MyFacesVisitHints.SKIP_ITERATION_HINT, Boolean.TRUE);
VisitContext visitContext = VisitContext.createVisitContext(facesContext, null, MyFacesVisitHints.SET_SKIP_ITERATION);
facesContext.getViewRoot().visitTree(visitContext, PreDisposeViewCallback.INSTANCE);
} finally {
facesContext.getAttributes().remove(MyFacesVisitHints.SKIP_ITERATION_HINT);
}
}
applyFlowTransition(facesContext, navigationContext);
// Dispose view if the view has been marked as disposable by default action listener
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
if (processor != null && processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot())) {
processor.disposeView(facesContext, facesContext.getViewRoot());
}
// create UIViewRoot for new view
UIViewRoot viewRoot = null;
String derivedViewId = viewHandler.deriveViewId(facesContext, newViewId);
if (derivedViewId != null) {
ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(facesContext, derivedViewId);
if (vdl != null) {
ViewMetadata metadata = vdl.getViewMetadata(facesContext, newViewId);
if (metadata != null) {
viewRoot = metadata.createMetadataView(facesContext);
}
}
}
// - viewHandler.deriveViewId() returned null
if (viewRoot == null) {
viewRoot = viewHandler.createView(facesContext, newViewId);
}
facesContext.setViewRoot(viewRoot);
facesContext.renderResponse();
}
} else {
// no navigationcase found, stay on current ViewRoot
if (log.isLoggable(Level.FINEST)) {
log.finest("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + " no matching navigation-case found, staying on current ViewRoot");
}
}
}
use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.
the class ViewPoolFaceletsTestCase method testDynPageResourceCleanup1.
/**
* Check remove component resource added using h:outputScript
*
* @throws Exception
*/
@Test
public void testDynPageResourceCleanup1() throws Exception {
facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
// Store structure for state checkA=false
facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.FALSE);
UIViewRoot root = facesContext.getViewRoot();
vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
processor.storeViewStructureMetadata(facesContext, root);
// Store structure for state checkA=true
facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.TRUE);
root = new UIViewRoot();
root.setViewId("/test");
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
facesContext.setViewRoot(root);
vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
processor.storeViewStructureMetadata(facesContext, root);
// Try change a view with state checkA=true to checkA=false
// change set filled view
facesContext.getAttributes().remove(root);
facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.FALSE);
vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
UIComponent headerFacet = root.getFacet("head");
int oldCount = headerFacet.getChildCount();
// the resource should still be there
// Assert.assertEquals(1, oldCount);
// The code in MYFACES-3659 reset the component after refresh
Assert.assertEquals(0, oldCount);
// Clear the view and synchronize resources
ViewStructureMetadata metadata = processor.retrieveViewStructureMetadata(facesContext, root);
Assert.assertNotNull(metadata);
processor.clearTransientAndNonFaceletComponentsForDynamicView(facesContext, root, metadata);
// the resource added by state checkA=true should not be there
Assert.assertEquals(0, headerFacet.getChildCount());
}
use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.
the class ViewPoolMyFacesRequestTestCase method testStaticPage1_6.
@Test
public void testStaticPage1_6() throws Exception {
Locale locale = null;
startViewRequest("/staticPage3.xhtml");
processLifecycleExecute();
locale = facesContext.getViewRoot().getLocale();
facesContext.getViewRoot().getViewMap().put("keyBeforeView", "someBeforeValue");
executeBeforeRender(facesContext);
executeBuildViewCycle(facesContext);
// Use view scope
Assert.assertEquals("someBeforeValue", facesContext.getViewRoot().getViewMap().get("keyBeforeView"));
facesContext.getViewRoot().getViewMap().put("someKey", "someValue");
UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
executeViewHandlerRender(facesContext);
executeAfterRender(facesContext);
client.submit(submitButton);
processLifecycleExecute();
executeBeforeRender(facesContext);
executeBuildViewCycle(facesContext);
// Check if the view scope value is preserved
Assert.assertEquals("someValue", facesContext.getViewRoot().getViewMap().get("someKey"));
facesContext.getViewRoot().getViewMap().put("someKey", "someValue2");
submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
executeViewHandlerRender(facesContext);
executeAfterRender(facesContext);
client.submit(submitButton);
processLifecycleExecute();
executeBeforeRender(facesContext);
executeBuildViewCycle(facesContext);
// Check if the view scope value is preserved
Assert.assertEquals("someValue2", facesContext.getViewRoot().getViewMap().get("someKey"));
Assert.assertTrue(facesContext.getViewRoot().getChildCount() > 0);
executeViewHandlerRender(facesContext);
executeAfterRender(facesContext);
UIViewRoot root = new UIViewRoot();
root.setLocale(locale);
root.setRenderKitId("HTML_BASIC");
root.setViewId("/staticPage3.xhtml");
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
ViewPool viewPool = processor.getViewPool(facesContext, root);
ViewEntry entry = viewPool.popStaticOrPartialStructureView(facesContext, root);
Assert.assertNotNull(entry);
Assert.assertEquals(RestoreViewFromPoolResult.COMPLETE, entry.getResult());
endRequest();
}
use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.
the class ViewPoolMyFacesRequestTestCase method testPartialPage1_1.
@Test
public void testPartialPage1_1() throws Exception {
Locale locale = null;
startViewRequest("/partialPage1.xhtml");
processLifecycleExecute();
locale = facesContext.getViewRoot().getLocale();
executeBuildViewCycle(facesContext);
// Now let's try to remove some component programatically
// that invalidates the view to be reused without a refresh,
// so in the pool it should be marked as REFRESH_REQUIRED
UIPanel panel = (UIPanel) facesContext.getViewRoot().findComponent("mainForm:panel1");
panel.getParent().getChildren().remove(panel);
UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
executeViewHandlerRender(facesContext);
executeAfterRender(facesContext);
client.submit(submitButton);
processLifecycleExecute();
FaceletState faceletState = (FaceletState) facesContext.getViewRoot().getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
UIViewRoot root = new UIViewRoot();
root.setLocale(locale);
root.setRenderKitId("HTML_BASIC");
root.setViewId("/partialPage1.xhtml");
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
ViewPool viewPool = processor.getViewPool(facesContext, root);
// Check the view was used
ViewEntry entry2 = viewPool.popStaticOrPartialStructureView(facesContext, root);
Assert.assertNull(entry2);
ViewEntry entry3 = viewPool.popDynamicStructureView(facesContext, root, faceletState);
Assert.assertNull(entry3);
}
use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.
the class ViewPoolMyFacesRequestTestCase method testPartialPage1_2.
@Test
public void testPartialPage1_2() throws Exception {
Locale locale = null;
startViewRequest("/partialPage1.xhtml");
processLifecycleExecute();
locale = facesContext.getViewRoot().getLocale();
executeBuildViewCycle(facesContext);
// Now let's try to remove some component programatically
// that invalidates the view to be reused without a refresh,
// so in the pool it should be marked as REFRESH_REQUIRED
UIPanel panel = (UIPanel) facesContext.getViewRoot().findComponent("mainForm:panel1");
panel.getParent().getChildren().remove(panel);
facesContext.getViewRoot().getViewMap().put("someKey", "someValue");
UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
executeViewHandlerRender(facesContext);
executeAfterRender(facesContext);
client.submit(submitButton);
processLifecycleExecute();
Assert.assertEquals("someValue", facesContext.getViewRoot().getViewMap().get("someKey"));
FaceletState faceletState = (FaceletState) facesContext.getViewRoot().getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
UIViewRoot root = new UIViewRoot();
root.setLocale(locale);
root.setRenderKitId("HTML_BASIC");
root.setViewId("/partialPage1.xhtml");
ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
ViewPool viewPool = processor.getViewPool(facesContext, root);
// Check the view was used
ViewEntry entry2 = viewPool.popStaticOrPartialStructureView(facesContext, root);
Assert.assertNull(entry2);
ViewEntry entry3 = viewPool.popDynamicStructureView(facesContext, root, faceletState);
Assert.assertNull(entry3);
}
Aggregations