use of jakarta.faces.view.ViewMetadata 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 jakarta.faces.view.ViewMetadata in project myfaces by apache.
the class ViewHandlerImpl method getViewParameterList.
private Map<String, List<String>> getViewParameterList(FacesContext context, String viewId, Map<String, List<String>> parametersFromArg) {
UIViewRoot viewRoot = context.getViewRoot();
String currentViewId = viewRoot.getViewId();
Collection<UIViewParameter> toViewParams = null;
Collection<UIViewParameter> currentViewParams = ViewMetadata.getViewParameters(viewRoot);
if (currentViewId.equals(viewId)) {
toViewParams = currentViewParams;
} else {
String calculatedViewId = getViewIdSupport(context).deriveLogicalViewId(context, viewId);
// we cannot use this.getVDL() directly (see getViewHandler())
// ViewDeclarationLanguage vdl = getViewHandler(context).
// getViewDeclarationLanguage(context, calculatedViewId);
// -= Leonardo Uribe =- Temporally reverted by TCK issues.
ViewDeclarationLanguage vdl = getViewDeclarationLanguage(context, calculatedViewId);
ViewMetadata viewMetadata = vdl.getViewMetadata(context, viewId);
if (viewMetadata != null) {
UIViewRoot viewFromMetaData = viewMetadata.createMetadataView(context);
toViewParams = ViewMetadata.getViewParameters(viewFromMetaData);
}
}
if (toViewParams == null || toViewParams.isEmpty()) {
return parametersFromArg;
}
// we need to use a custom Map to add the view parameters,
// otherwise the current value of the view parameter will be added to
// the navigation case as a static (!!!) parameter, thus the value
// won't be updated on any following request
// (Note that parametersFromArg is the Map from the NavigationCase)
// Also note that we don't have to copy the Lists, because they won't be changed
Map<String, List<String>> parameters = new HashMap<>(parametersFromArg);
for (UIViewParameter viewParameter : toViewParams) {
if (!parameters.containsKey(viewParameter.getName())) {
String parameterValue = viewParameter.getStringValueFromModel(context);
if (parameterValue == null) {
if (currentViewId.equals(viewId)) {
parameterValue = viewParameter.getStringValue(context);
} else {
if (viewParameter.getName() != null) {
for (UIViewParameter curParam : currentViewParams) {
if (viewParameter.getName().equals(curParam.getName())) {
parameterValue = curParam.getStringValue(context);
break;
}
}
}
}
}
if (parameterValue != null) {
// since we have checked !parameters.containsKey(viewParameter.getName())
// here already, the parameters Map will never contain a List under the
// key viewParameter.getName(), thus we do not have to check it here (again).
List<String> parameterValueList = new ArrayList<>(1);
parameterValueList.add(parameterValue);
parameters.put(viewParameter.getName(), parameterValueList);
}
}
}
return parameters;
}
use of jakarta.faces.view.ViewMetadata in project myfaces by apache.
the class UIViewRoot method encodeEnd.
@Override
public void encodeEnd(FacesContext context) throws IOException {
Assert.notNull(context, "context");
if (!context.getResponseComplete()) {
super.encodeEnd(context);
// the call to encodeAll() on every UIViewParameter here is only necessary
// if the current request is _not_ an AJAX request, because if it was an
// AJAX request, the call would already have happened in PartialViewContextImpl and
// would anyway be too late here, because the state would already have been generated
PartialViewContext partialContext = context.getPartialViewContext();
if (!partialContext.isAjaxRequest()) {
ViewDeclarationLanguage vdl = context.getApplication().getViewHandler().getViewDeclarationLanguage(context, getViewId());
if (vdl != null) {
// If the current view has view parameters, as indicated by a non-empty
// and non-UnsupportedOperationException throwing
// return from ViewDeclarationLanguage.getViewMetadata(jakarta.faces.context.FacesContext, String)
ViewMetadata metadata = null;
try {
metadata = vdl.getViewMetadata(context, getViewId());
} catch (UnsupportedOperationException e) {
_getLogger().log(Level.SEVERE, "Exception while obtaining the view metadata: " + e.getMessage(), e);
}
if (metadata != null) {
try {
Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(this);
if (!viewParams.isEmpty()) {
// call UIViewParameter.encodeAll(jakarta.faces.context.FacesContext) on each parameter.
for (UIViewParameter param : viewParams) {
param.encodeAll(context);
}
}
} catch (UnsupportedOperationException e) {
// If calling getViewParameters() causes UnsupportedOperationException
// to be thrown, the exception must be silently swallowed.
}
}
}
}
}
try {
notifyListeners(context, PhaseId.RENDER_RESPONSE, getAfterPhaseListener(), false);
} catch (Exception e) {
// following the spec we have to swallow the exception
_getLogger().log(Level.SEVERE, "Exception while processing phase listener: " + e.getMessage(), e);
}
}
use of jakarta.faces.view.ViewMetadata in project myfaces by apache.
the class FaceletViewDeclarationLanguageTest method testBuildViewUIViewParameters.
/**
* Test case for MYFACES-3002.
*/
@Test
public void testBuildViewUIViewParameters() throws Exception {
// build a UIViewRoot with a UIViewParameter
ViewMetadata viewMetadata = this.vdl.getViewMetadata(facesContext, "viewparameter1.xhtml");
UIViewRoot root = viewMetadata.createMetadataView(facesContext);
facesContext.setViewRoot(root);
// UIViewParameter must be there
checkUIViewParameter(root);
// build and render view (must not remove UIViewParameter)
vdl.buildView(facesContext, root, "viewparameter1.xhtml");
vdl.renderView(facesContext, root);
// UIViewParameter must still be there, because its value is saved in the state!
checkUIViewParameter(root);
}
use of jakarta.faces.view.ViewMetadata in project myfaces by apache.
the class ViewMetadataTestCase method testSimpleViewMetadata.
@Test
public void testSimpleViewMetadata() throws Exception {
HelloWorld helloWorld = new HelloWorld();
facesContext.getExternalContext().getRequestMap().put("helloWorldBean", helloWorld);
Set<NavigationCase> cases = new HashSet<NavigationCase>();
NavigationCase navCase = new NavigationCase("viewMetadata.xhtml", null, "somePage.xhtml", null, "somePage.xhtml", null, false, false);
cases.add(navCase);
navigationHandler.getNavigationCases().put("somePage.xhtml", cases);
navigationHandler.getNavigationCase(facesContext, null, "somePage.xhtml");
ViewMetadata metadata = vdl.getViewMetadata(facesContext, "viewMetadata.xhtml");
UIViewRoot root = metadata.createMetadataView(facesContext);
Collection<UIViewParameter> viewParameters = metadata.getViewParameters(root);
Assert.assertEquals(1, viewParameters.size());
// root.setViewId("viewMetadata.xhtml");
vdl.buildView(facesContext, root, "viewMetadata.xhtml");
facesContext.setViewRoot(root);
StringWriter sw = new StringWriter();
ResponseWriter mrw = new HtmlResponseWriterImpl(sw, "text/html", "UTF-8");
facesContext.setResponseWriter(mrw);
root.encodeAll(facesContext);
sw.flush();
System.out.print(sw.toString());
}
Aggregations