/**
* Copyright 2005-2010 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.validators;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hdiv.config.HDIVConfig;
import org.hdiv.util.HDIVErrorCodes;
import org.hdiv.util.UtilsJsf;
import org.hdiv.validation.ValidationError;
/**
* Validates that all parameters received in a request are valid and that
* no extra parameters has been added
*
* @author Gotzon Illarramendi
*/
public class RequestParameterValidator implements ComponentValidator {
private static Log log = LogFactory.getLog(RequestParameterValidator.class);
/**
* HDIV configuration
*/
private HDIVConfig hdivConfig;
/*
* (non-Javadoc)
*
* @see
* org.hdiv.validators.ComponentValidator#validate(javax.faces.component
* .UIComponent)
*/
public ValidationError validate(UIComponent component) {
UIForm form = (UIForm) component;
ValidationError error = this.validateRequestParameters(form);
return error;
}
/**
* Verifies that all the received parameters correspond to an attribute
* of the form that has been sent
*
* @param formComponent
* @return
*/
private ValidationError validateRequestParameters(UIForm formComponent) {
List clientIds = getClientIds(formComponent);
FacesContext fContext = FacesContext.getCurrentInstance();
boolean validParameter = true;
boolean validParameters = true;
ValidationError error = null;
Map requestParameters = fContext.getExternalContext().getRequestParameterMap();
Iterator it = requestParameters.entrySet().iterator();
while (it.hasNext()) {
String requestParamName = ((Entry) it.next()).getKey().toString().trim();
if (UtilsJsf.isFacesViewParamName(requestParamName)) {
continue;
}
// Row identifier is removed from parameter name if it is inside
// a datatable
String requestParamNameWithRowId = requestParamName;
requestParamName = UtilsJsf.removeRowId(requestParamName);
// In MyFaces, some clientId of tables contain a rowId
validParameter = ((clientIds.contains(requestParamName)) || (clientIds.contains(requestParamNameWithRowId)));
if (!validParameter) {
// It may be a parameter added in the client, for instance
// using JavaScript.
// In this case check if it is a userStartParameters
boolean isStartParam = this.hdivConfig.isStartParameter(requestParamName);
if (isStartParam) {
if (log.isDebugEnabled()) {
log.debug("Parameter '" + requestParamName + "' is a startParameter");
}
validParameter = true;
} else {
// It is not a startParameter, non expected parameter
// raise error
validParameter = false;
Object value = requestParameters.get(requestParamName);
String paramValue = "";
if (value != null) {
paramValue = value.toString();
}
error = new ValidationError(HDIVErrorCodes.PARAMETER_NOT_EXISTS, null, requestParamName, paramValue);
}
}
validParameters = validParameters && validParameter;
}
return error;
}
/**
* Stores all the component ids that are children of the form
*
* @param component
*/
private List getClientIds(UIForm component) {
FacesContext fContext = FacesContext.getCurrentInstance();
List clientIds = new ArrayList();
String submittedForm = component.getClientId(fContext);
clientIds.add(UtilsJsf.removeRowId(submittedForm));
this.getAllClientIds(component, clientIds);
// Add those parameters that are proprietary for each implementation
clientIds.addAll(UtilsJsf.getJSFImplementationParamNames(submittedForm));
return clientIds;
}
/**
* A�ade en 'clientIds' todas las ids de los componentes susceptibles de
* crear par�metros en la petici�n.
*
* Adds to 'clientIds' all the component ids susceptible to creating
* parameters in the request
*
* @param component
*/
private void getAllClientIds(UIComponent component, List clientIds) {
// In A4J there are components that are not children but facets
Iterator it = component.getFacetsAndChildren();
while (it.hasNext()) {
Object obj = it.next();
if (obj instanceof UIComponent) {
UIComponent uicom = (UIComponent) obj;
if (uicom instanceof UIParameter) {
UIParameter parameter = (UIParameter) uicom;
clientIds.add(parameter.getName());
} else {
FacesContext fContext = FacesContext.getCurrentInstance();
String id = UtilsJsf.removeRowId(uicom.getClientId(fContext));
clientIds.add(id);
}
getAllClientIds(uicom, clientIds);
}
}
}
public void setHdivConfig(HDIVConfig hdivConfig) {
this.hdivConfig = hdivConfig;
}
}