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

org.butterfaces.resolver.AjaxClientIdResolver Maven / Gradle / Ivy

There is a newer version: 3.5.0
Show newest version
package org.butterfaces.resolver;

import org.butterfaces.util.StringUtils;
import org.butterfaces.util.StringUtils;

import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.behavior.AjaxBehavior;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.component.html.HtmlForm;
import javax.faces.context.FacesContext;
import java.util.*;

/**
 * Resolves client id for all ajax render ids in an  {@link UIComponent}. This client ids should be readably by jquery.
 */
public class AjaxClientIdResolver {

    private final Set ajaxRenderClientIds = new HashSet<>();
    private final Set resolvedAjaxRenderClientIds = new HashSet<>();
    private final Set resolvedAjaxRenderJQueryClientIds = new HashSet<>();
    private final String jQueryRenderIDSelector;

    public AjaxClientIdResolver(final UIComponent component) {
        if (!(component instanceof ClientBehaviorHolder)) {
            throw new IllegalArgumentException("Component " + component.getClass() + " is not implementing ClientBehaviorHolder");
        }

        ajaxRenderClientIds.addAll(this.findClientIdsToDisableOnRequest((ClientBehaviorHolder) component));
        resolvedAjaxRenderClientIds.addAll(this.resolveClientIds(component, ajaxRenderClientIds));
        resolvedAjaxRenderJQueryClientIds.addAll(this.convertClientIdsToJQuerySelectorIds(resolvedAjaxRenderClientIds));
        jQueryRenderIDSelector = this.createJQueryIDSelector(resolvedAjaxRenderJQueryClientIds, component);
    }

    private String createJQueryIDSelector(final Collection jQueryReadableClientIds, final UIComponent component) {
        if ((null == jQueryReadableClientIds) || jQueryReadableClientIds.isEmpty()) {
            return "undefined";
        }

        final StringBuilder builder = new StringBuilder();

        final Iterator iterator = jQueryReadableClientIds.iterator();

        while (iterator.hasNext()) {
            final String jQueryReadableClientId = iterator.next();

            if (jQueryReadableClientId.equals("@all")) {
                builder.append("html");
            } else if (jQueryReadableClientId.equals("@form")) {
                final String clientIdOfSurroundingFormClientId = this.findClientIdOfSurroundingFormClientId(component);
                if (StringUtils.isNotEmpty(clientIdOfSurroundingFormClientId)) {
                    builder.append("#" + clientIdOfSurroundingFormClientId);
                }
            } else if (jQueryReadableClientId.equals("@this") || jQueryReadableClientId.equals("@none")) {
            } else {
                builder.append(jQueryReadableClientId);
            }

            if (iterator.hasNext()) {
                builder.append(", ");
            }
        }

        return builder.toString();
    }

    private Set findClientIdsToDisableOnRequest(final ClientBehaviorHolder clientBehaviorHolder) {
        final Set renderClientIds = new HashSet<>();
        if (!clientBehaviorHolder.getClientBehaviors().isEmpty()) {
            final Collection> clientBehaviors = clientBehaviorHolder.getClientBehaviors().values();

            for (List clientBehavior : clientBehaviors) {
                for (ClientBehavior behavior : clientBehavior) {
                    if (behavior instanceof AjaxBehavior) {
                        final AjaxBehavior ajaxBehavior = (AjaxBehavior) behavior;
                        for (String render : ajaxBehavior.getRender()) {
                            if (StringUtils.isNotEmpty(render)) {
                                renderClientIds.add(render.trim());
                            }
                        }
                    }
                }
            }
        }
        return renderClientIds;
    }

    private Set convertClientIdsToJQuerySelectorIds(final Collection clientIds) {
        final Set jQueryClientIds = new HashSet<>();

        for (String clientIdToConvert : clientIds) {
            if (clientIdToConvert.startsWith("@")) {
               jQueryClientIds.add(clientIdToConvert);
            } else {
                jQueryClientIds.add("#" + clientIdToConvert.replaceAll(":", "\\\\\\\\:"));
            }
        }

        return jQueryClientIds;
    }

    private Set resolveClientIds(final UIComponent component,
                                         final Collection clientIdsToResolve) {
        final Set resolvedClientIds = new HashSet<>();

        if ((null == clientIdsToResolve) || clientIdsToResolve.isEmpty()) {
            return resolvedClientIds;
        }

        for (String clientIdToResolve : clientIdsToResolve) {
            if (clientIdToResolve.trim().length() == 0) {
                continue;
            }

            if (clientIdToResolve.equals("@all") || clientIdToResolve.equals("@none") ||
                    clientIdToResolve.equals("@form") || clientIdToResolve.equals("@this")) {
                resolvedClientIds.add(clientIdToResolve);
            } else {
                resolvedClientIds.add(getResolvedId(component, clientIdToResolve));
            }
        }

        return resolvedClientIds;
    }

    private String getResolvedId(final UIComponent component, final String clientIdToResolve) {

        // some component does not return correct client id (i.e. table) so try it by using parent component
        final UIComponent resolvedComponent = this.resolveComponent(component, clientIdToResolve);

        if (resolvedComponent == null) {
            if (clientIdToResolve.charAt(0) == UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance())) {
                return clientIdToResolve.substring(1);
            }
            return clientIdToResolve;
        }

        return resolvedComponent.getClientId();
    }

    private UIComponent resolveComponent(final UIComponent component, final String clientIdToResolve) {
        if (component == null) {
            return null;
        }

        final UIComponent resolvedComponent = component.findComponent(clientIdToResolve);

        // recursive call
        return resolvedComponent != null ? resolvedComponent : this.resolveComponent(component.getParent(), clientIdToResolve);
    }

    private String findClientIdOfSurroundingFormClientId(final UIComponent component) {
        if (component instanceof HtmlForm) {
            return component.getClientId();
        }

        if (component.getParent() == null) {
            return null;
        }

        return findClientIdOfSurroundingFormClientId(component.getParent());
    }

    public Set getResolvedAjaxRenderClientIds() {
        return resolvedAjaxRenderClientIds;
    }

    public Set getAjaxRenderClientIds() {
        return ajaxRenderClientIds;
    }

    public Set getResolvedAjaxRenderJQueryClientIds() {
        return resolvedAjaxRenderJQueryClientIds;
    }

    public String getjQueryRenderIDSelector() {
        return jQueryRenderIDSelector;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy