Package org.springmodules.validation.valang.javascript.taglib

Source Code of org.springmodules.validation.valang.javascript.taglib.ValangRulesExportInterceptor

/*
* Copyright 2002-20085 the original author or authors.
*
* 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.springmodules.validation.valang.javascript.taglib;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.BaseCommandController;
import org.springmodules.validation.valang.ValangValidator;

/**
* Spring MVC interceptor implementation that will automatically export Valang validation rules that are used by any of
* the intercepted handlers into the the ModelAndView so that they are accessible to the custom tag
* <code>ValangValidateTag</code>.
* <p/>
* <p>
* Does nothing if the intercepted handler is neither an instance of <code>BaseCommandController</code>, nor a proxied
* <code>BaseCommandController</code>.
* </p>
* <p>
* This will also do nothing if the handler did not export a command object into the model. Obviously the rules will
* only be picked up from all validators of type {@link ValangValidator}.
*
* @author Oliver Hutchison
* @author Uri Boness
* @author Colin Yates
*
* @see ValangValidateTag
* @see ValangValidator
*/
public class ValangRulesExportInterceptor extends HandlerInterceptorAdapter {

    private static final Log logger = LogFactory.getLog(ValangRulesExportInterceptor.class);

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {

        BaseCommandController controller = retrieveBaseCommandControllerIfPossible(handler);
        if (controller == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Controller is of type " + controller.getClass() + " so ignoring");
            }
            return;
        }

        Map model = modelAndView.getModel();
        String commandName = controller.getCommandName();
        if (model == null || !model.containsKey(commandName)) {
            if (logger.isWarnEnabled()) {
                logger.debug("Handler '" + handler + "' did not export command object '" + controller.getCommandName()
                        + "'; no rules added to model");
            }
            return;
        }

        Validator[] validators = controller.getValidators();
        for (int i = 0; i < validators.length; i++) {
            if (!ValangValidator.class.isInstance(validators[i])) {
                continue;
            }

            if (logger.isDebugEnabled()) {
                logger.debug("Adding Valang rules from handler '" + handler + "' to model");
            }

            ValangValidator validator = (ValangValidator) validators[i];
            ValangJavaScriptTagUtils.addValangRulesToModel(commandName, validator.getRules(), model);
        }

    }

    /**
     * Convert the specified <code>handler</code> to a {@link BaseCommandController} if possible.
     *
     * <p>
     * If the <code>handler</code> is type compatible with a <code>BaseCommandController</code> then it will simply be
     * cast.
     * </p>
     * <p>
     * If the <code>handler</code> is a Spring JDK (or CGLIB) proxy, then it will unravelled and returned (assuming the
     * target is a <code>BaseCommandController</code>.
     * </p>
     * If neither of the above strategies work, <code>null</code> will be returned.
     *
     * @param handler
     *            the handler to convert to a <code>BaseCommandController</code>.
     * @return a <code>BaseCommandController</code> or <code>null</code> if <code>handler</code> cannot be converted.
     * @throws Exception
     */
    private BaseCommandController retrieveBaseCommandControllerIfPossible(Object handler) throws Exception {
        BaseCommandController baseCommandController = null;

        if (BaseCommandController.class.isAssignableFrom(handler.getClass())) {
            if (logger.isDebugEnabled()) {
                logger.debug("handler is type compatible, simply cast");
            }
            baseCommandController = (BaseCommandController) handler;
        } else if (AopUtils.isAopProxy(handler)) {
            if (logger.isDebugEnabled()) {
                logger.debug("handler is AOP proxy");
            }

            Advised advisedObject = (Advised) handler;
            Class proxiedClass = advisedObject.getTargetClass();
            Object target = advisedObject.getTargetSource().getTarget();

            // convert (if possible) the target.
            baseCommandController = retrieveBaseCommandControllerIfPossible(target);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Cannot convert handler to BaseCommandController");
        }
        return baseCommandController;
    }
}
TOP

Related Classes of org.springmodules.validation.valang.javascript.taglib.ValangRulesExportInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.