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

org.hdiv.components.support.OutcomeTargetComponentHelper Maven / Gradle / Ivy

/**
 * Copyright 2005-2016 hdiv.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.hdiv.components.support;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutcomeTarget;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 

* This class has been mostly copied from: com.sun.faces.renderkit.html_basic.OutcomeTargetRenderer *

*

* Copied method are responsible for generating the url of the link/button from the outcome of the component. *

*

* Only for JSF 2.0+ *

* @author Gotzon Illarramendi */ public class OutcomeTargetComponentHelper { private static final Log log = LogFactory.getLog(OutcomeTargetComponentHelper.class); protected static final Param[] EMPTY_PARAMS = new Param[0]; /** * Returns the url that the component would generate if it was a UIOutcomeTarget * @param context {@link FacesContext} instance * @param component {@link UIOutcomeTarget} instance * @return the url */ public String getUrl(FacesContext context, UIOutcomeTarget component) { NavigationCase navCase = getNavigationCase(context, component); String url = getEncodedTargetURL(context, component, navCase); return url; } /** * Invoke the {@link NavigationHandler} preemptively to resolve a {@link NavigationCase} for the outcome declared on the * {@link UIOutcomeTarget} component. The current view id is used as the from-view-id when matching navigation cases and the from-action * is assumed to be null. * * @param context the {@link FacesContext} for the current request * @param component the target {@link UIComponent} * * @return the NavigationCase represeting the outcome target */ protected NavigationCase getNavigationCase(FacesContext context, UIComponent component) { NavigationHandler navHandler = context.getApplication().getNavigationHandler(); if (!(navHandler instanceof ConfigurableNavigationHandler)) { // if (logger.isLoggable(Level.WARNING)) { // logger.log(Level.WARNING, // "jsf.outcome.target.invalid.navigationhandler.type", // component.getId()); // } log.warn("jsf.outcome.target.invalid.navigationhandler.type Componente:" + component.getId()); return null; } String outcome = ((UIOutcomeTarget) component).getOutcome(); if (outcome == null) { outcome = context.getViewRoot().getViewId(); // QUESTION should we avoid the call to getNavigationCase() and instead instantiate one explicitly? // String viewId = context.getViewRoot().getViewId(); // return new NavigationCase(viewId, null, null, null, viewId, false, false); } NavigationCase navCase = ((ConfigurableNavigationHandler) navHandler).getNavigationCase(context, null, outcome); if (navCase == null) { // if (logger.isLoggable(Level.WARNING)) { // logger.log(Level.WARNING, // "jsf.outcometarget.navigation.case.not.resolved", // component.getId()); // } log.warn("jsf.outcometarget.navigation.case.not.resolved Componente:" + component.getId()); } return navCase; } /** *

* Resolve the target view id and then delegate to * {@link ViewHandler#getBookmarkableURL(javax.faces.context.FacesContext, String, java.util.Map, boolean)} to produce a redirect URL, * which will add the page parameters if necessary and properly prioritizing the parameter overrides. *

* * @param context the {@link FacesContext} for the current request * @param component the target {@link UIComponent} * @param navCase the target navigation case * * @return an encoded URL for the provided navigation case */ protected String getEncodedTargetURL(FacesContext context, UIComponent component, NavigationCase navCase) { // FIXME getNavigationCase doesn't resolve the target viewId (it is part of CaseStruct) String toViewId = navCase.getToViewId(context); Map> params = getParamOverrides(component); addNavigationParams(navCase, params); return context.getApplication().getViewHandler().getBookmarkableURL(context, toViewId, params, isIncludeViewParams(component, navCase)); } protected boolean isIncludeViewParams(UIComponent component, NavigationCase navcase) { return (((UIOutcomeTarget) component).isIncludeViewParams() || navcase.isIncludeViewParams()); } protected Map> getParamOverrides(UIComponent component) { Map> params = new LinkedHashMap>(); Param[] declaredParams = getParamList(component); for (Param candidate : declaredParams) { // QUESTION shouldn't the trimming of name should be done elsewhere? // null value is allowed as a way to suppress page parameter if (candidate.name != null && candidate.name.trim().length() > 0) { candidate.name = candidate.name.trim(); List values = params.get(candidate.name); if (values == null) { values = new ArrayList(); params.put(candidate.name, values); } values.add(candidate.value); } } return params; } /** * @param command the command which may have parameters * * @return an array of parameters */ protected Param[] getParamList(UIComponent command) { if (command.getChildCount() > 0) { ArrayList parameterList = new ArrayList(); for (UIComponent kid : command.getChildren()) { if (kid instanceof UIParameter) { UIParameter uiParam = (UIParameter) kid; if (!uiParam.isDisable()) { Object value = uiParam.getValue(); Param param = new Param(uiParam.getName(), (value == null ? null : value.toString())); parameterList.add(param); } } } return parameterList.toArray(new Param[parameterList.size()]); } else { return EMPTY_PARAMS; } } protected void addNavigationParams(NavigationCase navCase, Map> existingParams) { Map> navParams = navCase.getParameters(); if (navParams == null || navParams.isEmpty()) { return; } for (Map.Entry> entry : navParams.entrySet()) { String navParamName = entry.getKey(); // only add the navigation params to the existing params collection // if the parameter name isn't already present within the existing // collection if (!existingParams.containsKey(navParamName)) { existingParams.put(navParamName, entry.getValue()); } } } /** *

* Simple class to encapsulate the name and value of a UIParameter. */ public static class Param { public String name; public String value; // -------------------------------------------------------- Constructors public Param(String name, String value) { this.name = name; this.value = value; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy