001/*
002 * Copyright (C) 2007 Exadel, Inc.
003 *
004 * This library is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Lesser General Public
006 * License version 2.1 as published by the Free Software Foundation.
007 *
008 * This library is distributed in the hope that it will be useful,
009 * but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
011 * Lesser General Public License for more details.
012 *
013 * You should have received a copy of the GNU Lesser General Public
014 * License along with this library; if not, write to the Free Software
015 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
016 *
017 * Rich Faces - Natural Ajax for Java Server Faces (JSF)
018 *
019 * Contributors:
020 *     Anahide Tchertchian
021 */
022package org.nuxeo.ecm.platform.ui.web.util;
023
024import java.util.Iterator;
025
026import javax.faces.component.NamingContainer;
027import javax.faces.component.UIComponent;
028import javax.faces.component.UINamingContainer;
029import javax.faces.context.FacesContext;
030
031/**
032 * Helper methods for manipulating components thanks to given ids.
033 * <p>
034 * Most of helpers come from RichFaces 3.3.1 code (aligned on JSF 1.2).
035 *
036 * @since 6.0
037 */
038public class ComponentRenderUtils {
039
040    public static String getComponentAbsoluteId(UIComponent base, String targetId) {
041        if (targetId == null || targetId.startsWith(":")) {
042            return targetId;
043        }
044        String id = targetId;
045        UIComponent target = findComponentFor(base, id);
046        if (target != null) {
047            id = getAbsoluteId(target);
048        }
049        return id;
050    }
051
052    public static UIComponent getComponent(UIComponent base, String targetId) {
053        String id = getComponentAbsoluteId(base, targetId);
054        FacesContext ctx = FacesContext.getCurrentInstance();
055        UIComponent anchor = ctx.getViewRoot().findComponent(id);
056        return anchor;
057    }
058
059    public static UIComponent findComponentFor(UIComponent component, String id) {
060        if (id == null) {
061            throw new NullPointerException("id is null!");
062        }
063        if (id.length() == 0) {
064            return null;
065        }
066        UIComponent target = null;
067        UIComponent parent = component;
068        UIComponent root = component;
069        while (target == null && parent != null) {
070            target = findUIComponentBelow(parent, id);
071            root = parent;
072            parent = parent.getParent();
073        }
074        if (target == null) {
075            target = findUIComponentBelow(root, id);
076        }
077        return target;
078    }
079
080    protected static UIComponent findUIComponentBelow(UIComponent root, String id) {
081        UIComponent target = null;
082        for (Iterator<UIComponent> iter = root.getFacetsAndChildren(); iter.hasNext();) {
083            UIComponent child = iter.next();
084            if (child instanceof NamingContainer) {
085                try {
086                    target = child.findComponent(id);
087                } catch (IllegalArgumentException iae) {
088                    continue;
089                }
090            }
091            if (target == null && child.getChildCount() > 0) {
092                target = findUIComponentBelow(child, id);
093            }
094            if (target != null) {
095                break;
096            }
097        }
098        return target;
099    }
100
101    public static String getAbsoluteId(UIComponent component) {
102        FacesContext faces = FacesContext.getCurrentInstance();
103        return UINamingContainer.getSeparatorChar(faces) + component.getClientId(FacesContext.getCurrentInstance());
104    }
105
106}