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

org.richfaces.renderkit.html.ClientValidatorRenderer Maven / Gradle / Ivy

There is a newer version: 4.3.7.Final
Show newest version
package org.richfaces.renderkit.html;

//
// Imports
//

import java.util.Collection;
import java.util.List;

import javax.faces.FacesException;
import javax.faces.component.ActionSource;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorContext;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.PhaseId;
import javax.faces.render.ClientBehaviorRenderer;

import org.ajax4jsf.javascript.JSReference;
import org.ajax4jsf.javascript.ScriptUtils;
import org.richfaces.application.ServiceTracker;
import org.richfaces.component.behavior.ClientValidatorBehavior;
import org.richfaces.component.behavior.ConverterNotFoundException;
import org.richfaces.javascript.ClientScriptService;
import org.richfaces.javascript.JavaScriptService;
import org.richfaces.javascript.LibraryFunction;
import org.richfaces.javascript.ScriptNotFoundException;
import org.richfaces.validator.ConverterDescriptor;
import org.richfaces.validator.FacesObjectDescriptor;
import org.richfaces.validator.ValidatorDescriptor;

import com.google.common.collect.Lists;

/**
 * Renderer for component class org.richfaces.renderkit.html.AjaxValidatorRenderer
 */
public class ClientValidatorRenderer extends ClientBehaviorRenderer {
    public static final String RENDERER_TYPE = "org.richfaces.ClientValidatorRenderer";
    public static final String VALUE_VAR = "value";
    public static final String CONVERTED_VALUE_VAR = "convertedValue";
    public static final JSReference VALUE_LITERAL = new JSReference("value");
    public static final JSReference CONVERTED_VALUE_LITERAL = new JSReference("convertedValue");

    public ClientValidatorRenderer() {
        super();
    }

    @Override
    public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {
        if (null == behaviorContext) {
            throw new NullPointerException();
        }
        if (null == behavior) {
            throw new NullPointerException();
        }
        if (behavior instanceof ClientValidatorBehavior) {
            ClientValidatorBehavior clientValidator = (ClientValidatorBehavior) behavior;
            if (clientValidator.isDisabled()) {
                return null;
            } else {
                return buildAndStoreValidatorScript(behaviorContext, clientValidator);
            }
        } else {
            throw new FacesException(
                    "ClientBehavior for ClientValidatorRenderer does not implement ClientValidatorBehavior interface");
        }
    }

    @Override
    public void decode(FacesContext context, UIComponent component, ClientBehavior behavior) {
        if (null == context || null == component || null == behavior) {
            throw new NullPointerException();
        }

        if (!(behavior instanceof ClientValidatorBehavior)) {
            throw new IllegalArgumentException(
                    "Instance of org.ruchvaces.component.behaviot.ClientValidatorBehavior required: " + behavior);
        }
        ClientValidatorBehavior ajaxBehavior = (ClientValidatorBehavior) behavior;

        // First things first - if AjaxBehavior is disabled, we are done.
        if (!ajaxBehavior.isDisabled()) {
            component.queueEvent(createEvent(component, ajaxBehavior));
        }
    }

    // Creates an AjaxBehaviorEvent for the specified component/behavior
    private static AjaxBehaviorEvent createEvent(UIComponent component, ClientValidatorBehavior ajaxBehavior) {

        AjaxBehaviorEvent event = new AjaxBehaviorEvent(component, ajaxBehavior);

        PhaseId phaseId = isImmediate(component, ajaxBehavior) ? PhaseId.APPLY_REQUEST_VALUES : PhaseId.PROCESS_VALIDATIONS;

        event.setPhaseId(phaseId);

        return event;
    }

    // Tests whether we should perform immediate processing. Note
    // that we "inherit" immediate from the parent if not specified
    // on the behavior.
    private static boolean isImmediate(UIComponent component, ClientValidatorBehavior ajaxBehavior) {

        boolean immediate = false;

        if (ajaxBehavior.isImmediateSet()) {
            immediate = ajaxBehavior.isImmediate();
        } else if (component instanceof EditableValueHolder) {
            immediate = ((EditableValueHolder) component).isImmediate();
        } else if (component instanceof ActionSource) {
            immediate = ((ActionSource) component).isImmediate();
        }

        return immediate;
    }

    /**
     * 

* This method builds client-side validation script and stores it in View resource component *

* * @param behaviorContext * @param behavior * @return name of the JavaScript function to call */ String buildAndStoreValidatorScript(ClientBehaviorContext behaviorContext, ClientValidatorBehavior behavior) { ComponentValidatorScript validatorScript = createValidatorScript(behaviorContext, behavior); if (null != validatorScript) { FacesContext facesContext = behaviorContext.getFacesContext(); JavaScriptService javaScriptService = ServiceTracker.getService(JavaScriptService.class); validatorScript = javaScriptService.addScript(facesContext, validatorScript); return validatorScript.createCallScript(behaviorContext.getComponent().getClientId(facesContext), behaviorContext.getSourceId()); } else { return null; } } ComponentValidatorScript createValidatorScript(ClientBehaviorContext behaviorContext, ClientValidatorBehavior behavior) { ValidatorScriptBase validatorScript; Collection validators = behavior.getValidators(behaviorContext); if (!validators.isEmpty()) { try { ConverterDescriptor converter = behavior.getConverter(behaviorContext); if (null != converter) { try { LibraryScriptFunction clientSideConverterScript = getClientSideConverterScript( behaviorContext.getFacesContext(), converter); validatorScript = createValidatorScript(behaviorContext, behavior, validators, clientSideConverterScript); } catch (ScriptNotFoundException e) { // ajax-only validation validatorScript = new AjaxOnlyScript(createAjaxScript(behaviorContext, behavior)); } } else { validatorScript = createValidatorScript(behaviorContext, behavior, validators, null); } } catch (ConverterNotFoundException e) { // fallback to ajax-only validation validatorScript = new AjaxOnlyScript(createAjaxScript(behaviorContext, behavior)); } String clientId = getComponentClientId(behaviorContext); String name = ScriptUtils.getValidJavascriptName(validatorScript.toScript()); validatorScript.setName(name); return validatorScript; } else { // No validation required. return null; } } private String getComponentClientId(ClientBehaviorContext behaviorContext) { return behaviorContext.getComponent().getClientId(behaviorContext.getFacesContext()); } private ValidatorScriptBase createValidatorScript(ClientBehaviorContext behaviorContext, ClientValidatorBehavior behavior, Collection validators, LibraryScriptFunction clientSideConverterScript) { Collection validatorScripts = getClientSideValidatorScript( behaviorContext.getFacesContext(), validators); if (validatorScripts.isEmpty()) { return new AjaxOnlyScript(createAjaxScript(behaviorContext, behavior)); } else if (validatorScripts.size() < validators.size()) { return new ClientAndAjaxScript(clientSideConverterScript, validatorScripts, createAjaxScript(behaviorContext, behavior), behavior.getOnvalid(), behavior.getOninvalid()); } else { return new ClientOnlyScript(clientSideConverterScript, validatorScripts, behavior.getOnvalid(), behavior.getOninvalid()); } } private String createAjaxScript(ClientBehaviorContext behaviorContext, ClientValidatorBehavior behavior) { String ajaxScript = behavior.getAjaxScript(behaviorContext); String clientId = getComponentClientId(behaviorContext); ajaxScript = replaceTextToVariable(ajaxScript, clientId, ValidatorScriptBase.CLIENT_ID); String sourceId = behaviorContext.getSourceId(); if (null != sourceId) { // TODO - send sourceId as separate parameter. ajaxScript = replaceTextToVariable(ajaxScript, sourceId, ValidatorScriptBase.ELEMENT); } return ajaxScript; } private String replaceTextToVariable(String ajaxScript, String clientId, String variableName) { ajaxScript = ajaxScript.replace("'" + clientId + "'", variableName); ajaxScript = ajaxScript.replace("\"" + clientId + "\"", variableName); return ajaxScript; } /** *

* Build client-side function call for Server-side component descriptor. *

* * @param behaviorContext * @param validator * @return * @throws ScriptNotFoundException */ /** *

*

* * @param behaviorContext * @param converter * @return * @throws ScriptNotFoundException */ LibraryScriptFunction getClientSideConverterScript(FacesContext facesContext, ConverterDescriptor converter) throws ScriptNotFoundException { ClientScriptService clientScriptService = ServiceTracker.getService(facesContext, ClientScriptService.class); return createClientFunction(facesContext, converter, clientScriptService); } private LibraryScriptFunction createClientFunction(FacesContext facesContext, FacesObjectDescriptor descriptor, ClientScriptService clientScriptService) throws ScriptNotFoundException { LibraryFunction script = clientScriptService.getScript(facesContext, descriptor.getImplementationClass()); return new LibraryScriptFunction(script, descriptor.getMessage(), descriptor.getAdditionalParameters()); } /** *

* Build client-side function call for Server-side component descriptor. *

* * @param facesContext * @param validators * @return * @throws ScriptNotFoundException */ Collection getClientSideValidatorScript(FacesContext facesContext, Collection validators) { ClientScriptService clientScriptService = ServiceTracker.getService(facesContext, ClientScriptService.class); List scripts = Lists.newArrayList(); for (FacesObjectDescriptor validator : validators) { try { scripts.add(createClientFunction(facesContext, validator, clientScriptService)); } catch (ScriptNotFoundException e) { // Skip this validator for AJAX call. } } return scripts; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy