All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.config.processor.NavigationConfigProcessor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.config.processor;

import static java.text.MessageFormat.format;
import static java.util.logging.Level.FINE;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.config.manager.documents.DocumentInfo;
import com.sun.faces.util.FacesLogger;

import jakarta.faces.application.ConfigurableNavigationHandler;
import jakarta.faces.application.NavigationCase;
import jakarta.faces.application.NavigationHandler;
import jakarta.faces.context.FacesContext;
import jakarta.servlet.ServletContext;

/**
 * 

* This ConfigProcessor handles all elements defined under /faces-config/navigation-rule. *

*/ public class NavigationConfigProcessor extends AbstractConfigProcessor { private static final Logger LOGGER = FacesLogger.CONFIG.getLogger(); /** *

* /faces-config/navigation-rule *

*/ private static final String NAVIGATION_RULE = "navigation-rule"; /** *

* /faces-config/navigation-rule/from-view-id *

*/ private static final String FROM_VIEW_ID = "from-view-id"; /** *

* /faces-config/navigation-rule/navigation-case *

*/ private static final String NAVIGATION_CASE = "navigation-case"; /** *

* /faces-config/navigation-rule/navigation-case/from-action *

*/ private static final String FROM_ACTION = "from-action"; /** *

* /faces-config/navigation-rule/navigation-case/from-outcome *

*/ private static final String FROM_OUTCOME = "from-outcome"; /** *

* /faces-config/navigation-rule/navigation-case/if *

*/ private static final String IF = "if"; /** *

* /faces-config/navigation-rule/navigation-case/to-view-id *

*/ private static final String TO_VIEW_ID = "to-view-id"; /** *

* /faces-config/navigation-rule/navigation-case/to-flow-document-id *

*/ private static final String TO_FLOW_DOCUMENT_ID = "to-flow-document-id"; /** *

* /faces-config/navigation-rule/navigation-case/redirect *

*/ private static final String REDIRECT = "redirect"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/view-param *

*/ private static final String VIEW_PARAM = "view-param"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/view-param/name *

*/ private static final String VIEW_PARAM_NAME = "name"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/view-param/value *

*/ private static final String VIEW_PARAM_VALUE = "value"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/redirect-param *

*/ private static final String REDIRECT_PARAM = "redirect-param"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/redirect-param/name *

*/ private static final String REDIRECT_PARAM_NAME = "name"; /** *

* /faces-confg/navigation-rule/navigation-case/redirect/redirect-param/value *

*/ private static final String REDIRECT_PARAM_VALUE = "value"; /** *

* /faces-config/navigation-rule/navigation-case/redirect[@include-page-params] *

*/ private static final String INCLUDE_VIEW_PARAMS_ATTRIBUTE = "include-view-params"; /** *

* If from-view-id is not defined. *

*/ private static final String FROM_VIEW_ID_DEFAULT = "*"; // -------------------------------------------- Methods from ConfigProcessor @Override public void process(ServletContext sc, FacesContext facesContext, DocumentInfo[] documentInfos) throws Exception { NavigationHandler handler = getApplication().getNavigationHandler(); for (DocumentInfo documentInfo : documentInfos) { if (LOGGER.isLoggable(FINE)) { LOGGER.log(FINE, format("Processing navigation-rule elements for document: ''{0}''", documentInfo.getSourceURI())); } Document document = documentInfo.getDocument(); String namespace = document.getDocumentElement().getNamespaceURI(); NodeList navigationRules = document.getDocumentElement().getElementsByTagNameNS(namespace, NAVIGATION_RULE); if (navigationRules != null && navigationRules.getLength() > 0) { addNavigationRules(navigationRules, handler, sc); } } } // --------------------------------------------------------- Private Methods private void addNavigationRules(NodeList navigationRules, NavigationHandler navHandler, ServletContext sc) throws XPathExpressionException { for (int i = 0, size = navigationRules.getLength(); i < size; i++) { Node navigationRule = navigationRules.item(i); if (!"flow-definition".equals(navigationRule.getParentNode().getLocalName()) && navigationRule.getNodeType() == Node.ELEMENT_NODE) { NodeList children = navigationRule.getChildNodes(); String fromViewId = FROM_VIEW_ID_DEFAULT; List navigationCases = null; for (int c = 0, csize = children.getLength(); c < csize; c++) { Node n = children.item(c); if (n.getNodeType() == Node.ELEMENT_NODE) { switch (n.getLocalName()) { case FROM_VIEW_ID: String t = getNodeText(n); fromViewId = t == null ? FROM_VIEW_ID_DEFAULT : t; if (!fromViewId.equals(FROM_VIEW_ID_DEFAULT) && fromViewId.charAt(0) != '/') { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.navigation.from_view_id_leading_slash", new String[] { fromViewId }); } fromViewId = '/' + fromViewId; } break; case NAVIGATION_CASE: if (navigationCases == null) { navigationCases = new ArrayList<>(csize); } navigationCases.add(n); break; } } } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, MessageFormat.format("Processing navigation rule with 'from-view-id' of ''{0}''", fromViewId)); } addNavigationCasesForRule(fromViewId, navigationCases, navHandler, sc); } } } private void addNavigationCasesForRule(String fromViewId, List navigationCases, NavigationHandler navHandler, ServletContext sc) { if (navigationCases != null && !navigationCases.isEmpty()) { ApplicationAssociate associate = ApplicationAssociate.getInstance(sc); for (Node navigationCase : navigationCases) { if (navigationCase.getNodeType() != Node.ELEMENT_NODE) { continue; } NodeList children = navigationCase.getChildNodes(); String outcome = null; String action = null; String condition = null; String toViewId = null; String toFlowDocumentId = null; Map> parameters = null; boolean redirect = false; boolean includeViewParams = false; for (int i = 0, size = children.getLength(); i < size; i++) { Node n = children.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { switch (n.getLocalName()) { case FROM_OUTCOME: outcome = getNodeText(n); break; case FROM_ACTION: action = getNodeText(n); break; case IF: String expression = getNodeText(n); if (SharedUtils.isExpression(expression) && !SharedUtils.isMixedExpression(expression)) { condition = expression; } else { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.navigation.if_invalid_expression", new String[] { expression, fromViewId }); } } break; case TO_VIEW_ID: String toViewIdString = getNodeText(n); if (toViewIdString.charAt(0) != '/' && toViewIdString.charAt(0) != '#') { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "faces.config.navigation.to_view_id_leading_slash", new String[] { toViewIdString, fromViewId }); } toViewId = '/' + toViewIdString; } else { toViewId = toViewIdString; } break; case TO_FLOW_DOCUMENT_ID: toFlowDocumentId = getNodeText(n); break; case REDIRECT: parameters = processParameters(n.getChildNodes()); includeViewParams = isIncludeViewParams(n); redirect = true; break; } } } NavigationCase cnc = new NavigationCase(fromViewId, action, outcome, condition, toViewId, toFlowDocumentId, parameters, redirect, includeViewParams); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, MessageFormat.format("Adding NavigationCase: {0}", cnc.toString())); } // if the top-level NavigationHandler is an instance of // ConfigurableNavigationHandler, add the NavigationCases to // that instance as well as adding them to the application associate. // We have to add them to the ApplicationAssociate in the case // where the top-level NavigationHandler may be custom and delegates // to the default NavigationHandler implementation. In 1.2, they // could be guaranteed that the default implementation had all // defined navigation mappings. if (navHandler instanceof ConfigurableNavigationHandler) { ConfigurableNavigationHandler cnav = (ConfigurableNavigationHandler) navHandler; Set cases = cnav.getNavigationCases().computeIfAbsent(fromViewId, k -> new LinkedHashSet<>()); cases.add(cnc); } associate.addNavigationCase(cnc); } } } private Map> processParameters(NodeList children) { Map> parameters = null; if (children.getLength() > 0) { parameters = new LinkedHashMap<>(4, 1.0f); for (int i = 0, size = children.getLength(); i < size; i++) { Node n = children.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (VIEW_PARAM.equals(n.getLocalName())) { String name = null; String value = null; NodeList params = n.getChildNodes(); for (int j = 0, jsize = params.getLength(); j < jsize; j++) { Node pn = params.item(j); if (pn.getNodeType() == Node.ELEMENT_NODE) { if (VIEW_PARAM_NAME.equals(pn.getLocalName())) { name = getNodeText(pn); } if (VIEW_PARAM_VALUE.equals(pn.getLocalName())) { value = getNodeText(pn); } } } if (name != null) { List values = parameters.get(name); if (values == null && value != null) { values = new ArrayList<>(2); parameters.put(name, values); } if (values != null) { values.add(value); } } } if (REDIRECT_PARAM.equals(n.getLocalName())) { String name = null; String value = null; NodeList params = n.getChildNodes(); for (int j = 0, jsize = params.getLength(); j < jsize; j++) { Node pn = params.item(j); if (pn.getNodeType() == Node.ELEMENT_NODE) { if (REDIRECT_PARAM_NAME.equals(pn.getLocalName())) { name = getNodeText(pn); } if (REDIRECT_PARAM_VALUE.equals(pn.getLocalName())) { value = getNodeText(pn); } } } if (name != null) { List values = parameters.get(name); if (values == null && value != null) { values = new ArrayList<>(2); parameters.put(name, values); } if (values != null) { values.add(value); } } } } } } return parameters; } private boolean isIncludeViewParams(Node n) { return Boolean.parseBoolean(getNodeText(n.getAttributes().getNamedItem(INCLUDE_VIEW_PARAMS_ATTRIBUTE))); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy