/*
* xulfaces : bring XUL power to Java
*
* Copyright (C) 2005 Olivier SCHMITT
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.xulfaces.renderer.tree;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.MethodBinding;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import org.xulfaces.MultiActionSource;
import org.xulfaces.annotation.faces.RENDERER;
import org.xulfaces.component.tree.TreeComponent;
import org.xulfaces.renderer.XULRenderer;
/**
* <p>Defines a renderer for Tree component.</p>
*
* @author kito31
* @version $Id: TreeRenderer.java,v 1.19 2007/04/01 17:09:00 kito31 Exp $
*/
@RENDERER(kit = "XUL_RENDERKIT", family = "xul.component.family", type = "xul.renderer.Tree")
public class TreeRenderer extends XULRenderer {
@Override
public void decode(FacesContext facesContext, UIComponent component) {
super.decode(facesContext, component);
TreeComponent treeComponent = (TreeComponent) component;
treeComponent.setSelectionPath(null);
if (isSubmitted(facesContext, component)) {
Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
String clientId = component.getClientId(facesContext);
if (paramMap.containsKey(clientId)) {
String selection = (String) paramMap.get(clientId);
if ((selection != null) && (selection.length() > 0)) {
String selections[] = selection.split(" ");
if (selections != null) {
// Get multi selections
TreePath[] selectionPaths = new TreePath[selections.length];
for (int i = 0; i < selections.length; i++) {
int tiIndex = selections[i].lastIndexOf("ti_");
if (tiIndex != -1) {
String path[] = selections[i].substring(tiIndex+3).split("_");
TreeNode selectedNodes[] = new TreeNode[path.length];
TreeNode currentNode = (TreeNode) treeComponent.getTreeModel().getRoot();
selectedNodes[0] = currentNode;
for (int j = 0; j < path.length; j++) {
String number = path[j];
int index = Integer.parseInt(number);
if (index < currentNode.getChildCount()) {
selectedNodes[j] = currentNode.getChildAt(index);
currentNode = selectedNodes[j];
}
}
selectionPaths[i] = new TreePath(selectedNodes);
}
}
treeComponent.setSelectionPath(selectionPaths);
}
}
}
Set<Entry> entries = paramMap.entrySet();
for (Entry entry : entries) {
String key = (String) entry.getKey();
if (key.startsWith(clientId)) {
treeComponent.getAttributes().put(key, entry.getValue());
}
}
}
}
@Override
public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
ResponseWriter responseWriter = facesContext.getResponseWriter();
responseWriter.startElement("tree",component);
responseWriter.writeAttribute("id", component.getClientId(facesContext), "id");
renderAttributes(facesContext,component,(List) component.getAttributes().get("annotatedAttributes"));
}
/**
* <p>Must override because tree selection needs to be sent with binded method name.</p>
*/
@Override
protected void renderBindedMethod(FacesContext facesContext, UIComponent component, String attributeName) throws IOException {
ResponseWriter responseWriter = facesContext.getResponseWriter();
StringBuffer stringBuffer = new StringBuffer();
MultiActionSource xulComponent = (MultiActionSource) component;
MethodBinding methodBinding = xulComponent.getMethodBinding(attributeName);
if(methodBinding != null){
stringBuffer.append("XUL_FACES_BRIDGE.saveTreeSelection(document.getElementById('");
stringBuffer.append(component.getClientId(facesContext));
stringBuffer.append("'));");
stringBuffer.append("triggerBindedMethod('");
stringBuffer.append(component.getClientId(facesContext));
stringBuffer.append("','");
stringBuffer.append(attributeName);
stringBuffer.append("');");
responseWriter.writeAttribute(attributeName, stringBuffer.toString(), attributeName);
}
}
@Override
public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
ResponseWriter responseWriter = facesContext.getResponseWriter();
responseWriter.endElement("tree");
}
@Override
public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException {
List<UIComponent> components = uiComponent.getChildren();
for(UIComponent child:components){
renderChild(facesContext,child);
}
}
@Override
public boolean getRendersChildren() {
return true;
}
}