/* * JBoss, Home of Professional Open Source * Copyright 2010, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.richfaces.renderkit; import static com.google.common.base.Strings.isNullOrEmpty; import static org.richfaces.renderkit.TreeRendererBase.getToggleTypeOrDefault; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.faces.context.FacesContext; import org.ajax4jsf.javascript.JSFunction; import org.ajax4jsf.javascript.JSReference; import org.ajax4jsf.javascript.ScriptStringBase; import org.ajax4jsf.javascript.ScriptUtils; import org.richfaces.component.AbstractTree; import org.richfaces.component.AbstractTreeNode; import org.richfaces.component.SwitchType; /** * @author Nick Belaevski * */ public final class TreeRenderingContext { private static final String ATTRIBUTE_NAME = TreeRenderingContext.class.getName() + ":ATTRIBUTE_NAME"; private static final ComponentAttribute ONTOGGLE_ATTRIBUTE = new ComponentAttribute("ontoggle").setEventNames("toggle"); private static final ComponentAttribute ONNODETOGGLE_ATTRIBUTE = new ComponentAttribute("onnodetoggle") .setEventNames("nodetoggle"); private static final ComponentAttribute ONBEFORETOGGLE_ATTRIBUTE = new ComponentAttribute("onbeforetoggle") .setEventNames("beforetoggle"); private static final ComponentAttribute ONBEFORENODETOGGLE_ATTRIBUTE = new ComponentAttribute("onbeforenodetoggle") .setEventNames("beforenodetoggle"); public static final class Handlers extends ScriptStringBase { private String toggleHandler; private String nodeToggleHandler; private String beforeToggleHandler; private String beforeNodeToggleHandler; protected Object chain(String firstHandler, String secondHandler) { if (isNullOrEmpty(firstHandler) && isNullOrEmpty(secondHandler)) { return null; } if (isNullOrEmpty(firstHandler)) { return secondHandler; } if (isNullOrEmpty(secondHandler)) { return firstHandler; } return new JSFunction("return jsf.util.chain", JSReference.THIS, JSReference.EVENT, firstHandler, secondHandler) .toScript(); } public void setToggleHandler(String toggleHandler) { this.toggleHandler = toggleHandler; } public String getToggleHandler() { return toggleHandler; } public void setNodeToggleHandler(String nodeToggleHandler) { this.nodeToggleHandler = nodeToggleHandler; } public String getNodeToggleHandler() { return nodeToggleHandler; } public void setBeforeToggleHandler(String beforeToggleHandler) { this.beforeToggleHandler = beforeToggleHandler; } public String getBeforeToggleHandler() { return beforeToggleHandler; } public void setBeforeNodeToggleHandler(String beforeNodeToggleHandler) { this.beforeNodeToggleHandler = beforeNodeToggleHandler; } public String getBeforeNodeToggleHandler() { return beforeNodeToggleHandler; } public void appendScript(Appendable target) throws IOException { Object chainedToggleHandler = chain(toggleHandler, nodeToggleHandler); Object chainedBeforeToggleHandler = chain(beforeToggleHandler, beforeNodeToggleHandler); if (chainedToggleHandler != null || chainedBeforeToggleHandler != null) { Map<String, Object> map = new HashMap<String, Object>(2); if (chainedToggleHandler != null) { map.put("th", chainedToggleHandler); } if (chainedBeforeToggleHandler != null) { map.put("bth", chainedBeforeToggleHandler); } ScriptUtils.appendScript(target, map); } else { ScriptUtils.appendScript(target, null); } } } private FacesContext context; private AbstractTree tree; private String baseClientId; private Map<String, Handlers> handlersMap = new HashMap<String, Handlers>(); private Handlers handlers; private TreeRenderingContext(FacesContext context, AbstractTree tree) { super(); this.context = context; this.tree = tree; this.baseClientId = tree.getClientId(context); } public static TreeRenderingContext create(FacesContext context, AbstractTree tree) { TreeRenderingContext renderingContext = new TreeRenderingContext(context, tree); context.getAttributes().put(ATTRIBUTE_NAME, renderingContext); return renderingContext; } public static TreeRenderingContext get(FacesContext context) { return (TreeRenderingContext) context.getAttributes().get(ATTRIBUTE_NAME); } public static void delete(FacesContext context) { context.getAttributes().remove(ATTRIBUTE_NAME); } private Handlers getOrCreateHandlers(String relativeClientId) { if (handlers == null) { handlers = new Handlers(); handlersMap.put(relativeClientId, handlers); } return handlers; } public void addHandlers(AbstractTreeNode treeNode) { handlers = null; String clientId = treeNode.getClientId(context); String relativeClientId = clientId.substring(baseClientId.length()); if (getToggleTypeOrDefault(tree) != SwitchType.server) { String toggleHandler = (String) RenderKitUtils.getAttributeAndBehaviorsValue(context, treeNode, ONTOGGLE_ATTRIBUTE); if (!isNullOrEmpty(toggleHandler)) { getOrCreateHandlers(relativeClientId).setToggleHandler(toggleHandler); } String beforeToggleHandler = (String) RenderKitUtils.getAttributeAndBehaviorsValue(context, treeNode, ONBEFORETOGGLE_ATTRIBUTE); if (!isNullOrEmpty(beforeToggleHandler)) { getOrCreateHandlers(relativeClientId).setBeforeToggleHandler(beforeToggleHandler); } String nodeToggleHandler = (String) RenderKitUtils.getAttributeAndBehaviorsValue(context, tree, ONNODETOGGLE_ATTRIBUTE); if (!isNullOrEmpty(nodeToggleHandler)) { getOrCreateHandlers(relativeClientId).setNodeToggleHandler(nodeToggleHandler); } String beforeNodeToggleHandler = (String) RenderKitUtils.getAttributeAndBehaviorsValue(context, tree, ONBEFORENODETOGGLE_ATTRIBUTE); if (!isNullOrEmpty(beforeNodeToggleHandler)) { getOrCreateHandlers(relativeClientId).setBeforeNodeToggleHandler(beforeNodeToggleHandler); } } } public Object getHandlers() { return handlersMap; } }