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