com.ocpsoft.pretty.faces.beans.ParameterValidator.java Source code

Java tutorial

Introduction

Here is the source code for com.ocpsoft.pretty.faces.beans.ParameterValidator.java

Source

/*
 * Copyright 2010 Lincoln Baxter, III
 * 
 * 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 com.ocpsoft.pretty.faces.beans;

import java.io.IOException;
import java.util.List;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletResponse;

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

import com.ocpsoft.pretty.PrettyContext;
import com.ocpsoft.pretty.PrettyException;
import com.ocpsoft.pretty.faces.config.mapping.PathParameter;
import com.ocpsoft.pretty.faces.config.mapping.PathValidator;
import com.ocpsoft.pretty.faces.config.mapping.QueryParameter;
import com.ocpsoft.pretty.faces.config.mapping.UrlMapping;
import com.ocpsoft.pretty.faces.url.URL;
import com.ocpsoft.pretty.faces.util.FacesElUtils;
import com.ocpsoft.pretty.faces.util.NullComponent;

/**
 * @author Lincoln Baxter, III <lincoln@ocpsoft.com>
 */
public class ParameterValidator {
    private static final Log log = LogFactory.getLog(ParameterInjector.class);
    private static final FacesElUtils elUtils = new FacesElUtils();

    public void validateParameters(final FacesContext context) {
        log.trace("Validating parameters.");
        PrettyContext prettyContext = PrettyContext.getCurrentInstance(context);
        URL url = prettyContext.getRequestURL();
        UrlMapping mapping = prettyContext.getCurrentMapping();

        if (mapping != null) {
            validatePathParams(context, url, mapping);
            validateQueryParams(context, mapping);
        }
    }

    private void validatePathParams(final FacesContext context, final URL url, final UrlMapping mapping) {
        List<PathParameter> params = mapping.getPatternParser().parse(url);

        PathParameter currentParameter = new PathParameter();
        PathValidator currentPathValidator = new PathValidator();
        String currentValidatorId = "";
        try {
            for (PathParameter param : params) {
                currentParameter = param;

                List<PathValidator> validators = mapping.getValidatorsForPathParam(param);

                if (validators != null && validators.size() > 0) {
                    String value = param.getValue();
                    Object coerced = elUtils.coerceToType(context, param.getExpression().getELExpression(), value);
                    for (PathValidator pv : validators) {
                        currentPathValidator = pv;
                        for (String id : pv.getValidatorIdList()) {
                            currentValidatorId = id;
                            Validator validator = context.getApplication().createValidator(id);
                            validator.validate(context, new NullComponent(), coerced);
                        }
                        if (pv.getValidatorExpression() != null) {
                            elUtils.invokeMethod(context, pv.getValidatorExpression().getELExpression(),
                                    new Class<?>[] { FacesContext.class, UIComponent.class, Object.class },
                                    new Object[] { context, new NullComponent(), coerced });
                        }
                    }
                }
            }
        } catch (ELException e) {
            FacesMessage message = new FacesMessage(
                    "Could not coerce value [" + currentParameter.getValue() + "] on mappingId [" + mapping.getId()
                            + "] to type in location [" + currentParameter.getExpression() + "]");
            handleValidationFailure(context, message, currentPathValidator.getOnError());
        } catch (ValidatorException e) {
            handleValidationFailure(context, e.getFacesMessage(), currentPathValidator.getOnError());
        } catch (FacesException e) {
            FacesMessage message = new FacesMessage("Error occurred invoking validator with id ["
                    + currentValidatorId + "] on mappingId [" + mapping.getId() + "] parameter ["
                    + currentParameter.getExpression() + "] at position [" + currentParameter.getPosition() + "]");
            handleValidationFailure(context, message, currentPathValidator.getOnError());
        }
    }

    private void validateQueryParams(final FacesContext context, final UrlMapping mapping) {
        QueryParameter currentParameter = new QueryParameter();
        String currentValidatorId = "";
        try {
            List<QueryParameter> params = mapping.getQueryParams();
            for (QueryParameter param : params) {
                if (param.hasValidators() || (param.getValidatorExpression() != null)) {
                    currentParameter = param;

                    String name = param.getName();
                    String el = param.getExpression().getELExpression();

                    if (elUtils.getExpectedType(context, el).isArray()) {
                        String[] values = context.getExternalContext().getRequestParameterValuesMap().get(name);
                        if (values != null) {
                            Object coerced = elUtils.coerceToType(context, el, values);
                            for (String id : param.getValidatorIdList()) {
                                currentValidatorId = id;
                                Validator validator = context.getApplication().createValidator(id);
                                validator.validate(context, new NullComponent(), coerced);
                            }
                            if (param.getValidatorExpression() != null) {
                                elUtils.invokeMethod(context, param.getValidatorExpression().getELExpression(),
                                        new Class<?>[] { FacesContext.class, UIComponent.class, Object.class },
                                        new Object[] { context, new NullComponent(), coerced });
                            }
                        }
                    } else {
                        String value = context.getExternalContext().getRequestParameterMap().get(name);
                        if (value != null) {
                            Object coerced = elUtils.coerceToType(context, el, value);
                            for (String id : param.getValidatorIdList()) {
                                currentValidatorId = id;
                                Validator validator = context.getApplication().createValidator(id);
                                validator.validate(context, new NullComponent(), coerced);
                            }
                            if (param.getValidatorExpression() != null) {
                                elUtils.invokeMethod(context, param.getValidatorExpression().getELExpression(),
                                        new Class<?>[] { FacesContext.class, UIComponent.class, Object.class },
                                        new Object[] { context, new NullComponent(), coerced });
                            }
                        }
                    }
                }
            }
        } catch (ELException e) {
            FacesMessage message = new FacesMessage("Could not coerce value [" + currentParameter.getValue()
                    + "] on mappingId [" + mapping.getId() + "] to type ["
                    + elUtils.getExpectedType(context, currentParameter.getExpression().getELExpression()) + "]");
            handleValidationFailure(context, message, currentParameter.getOnError());
        } catch (ValidatorException e) {
            handleValidationFailure(context, e.getFacesMessage(), currentParameter.getOnError());
        } catch (FacesException e) {
            FacesMessage message = new FacesMessage(
                    "Error occurred invoking validator with id [" + currentValidatorId + "] on mappingId ["
                            + mapping.getId() + "] parameter [" + currentParameter.getName() + "]");
            handleValidationFailure(context, message, currentParameter.getOnError());
        }
    }

    private void handleValidationFailure(final FacesContext context, final FacesMessage message, String onError) {
        boolean continueToFaces = false;
        if ((onError != null) && !"".equals(onError.trim())) {
            if (elUtils.isEl(onError)) {
                Object result = elUtils.invokeMethod(context, onError);
                if (result == null) {
                    continueToFaces = true;
                } else {
                    onError = result.toString();
                }
            }

            if (onError != null) {
                String viewId = context.getViewRoot().getViewId();
                context.getApplication().getNavigationHandler().handleNavigation(context, viewId, onError);
            }
        }

        if (!context.getResponseComplete() && !continueToFaces) {
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
            try {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                context.responseComplete();
            } catch (IOException e1) {
                throw new PrettyException(e1);
            }
        }
    }

}