/* TreeSelectedItemsConverter.java Purpose: Description: History: Aug 17, 2011 6:10:20 PM, Created by dennis Copyright (C) 2011 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.converter.sys; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; import org.zkoss.bind.BindContext; import org.zkoss.bind.Converter; import org.zkoss.lang.Classes; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; import org.zkoss.zul.Tree; import org.zkoss.zul.TreeModel; import org.zkoss.zul.Treeitem; import org.zkoss.zul.ext.TreeSelectableModel; /** * Convert tree selected treeitem to bean and vice versa. * @author dennis * @since 6.0.0 */ public class TreeSelectedItemsConverter implements Converter, java.io.Serializable { private static final long serialVersionUID = 201108171811L; @SuppressWarnings("unchecked") public Object coerceToUi(Object val, Component comp, BindContext ctx) { Tree tree = (Tree) comp; final TreeModel<Object> model = tree.getModel(); if (model != null && !(model instanceof TreeSelectableModel)) { //model has to implement TreeSelectableModel if binding to selectedItem throw new UiException("model doesn't implement " + TreeSelectableModel.class); } final TreeSelectableModel smodel = (TreeSelectableModel) model; final Set<Treeitem> items = new LinkedHashSet<Treeitem>(); Set<Object> vals = val == null ? null : (Set<Object>) Classes.coerce(LinkedHashSet.class, val); if (smodel != null && !smodel.isSelectionEmpty()) { //clear the selection first smodel.clearSelection(); } if (vals != null && vals.size() > 0) { if (model != null) { for (Object v : vals) { int[] path = model.getPath(v); if (path != null & smodel != null) { smodel.addSelectionPath(path); } //what if a model is not a tree selection model, there has same issue if a treeitem is not rendered yet as zk-766 event we } return IGNORED_VALUE; } //no model case //and if user want better performance, he should get the selection from model directly for (final Iterator<?> it = tree.getItems().iterator(); it.hasNext();) { final Treeitem ti = (Treeitem) it.next(); //TODO get value form BinderImpl.VAR (Reference) for better performance //final String varnm = (String) ti.getAttribute(BinderImpl.VAR); Object bean = ti.getValue(); if (vals.contains(bean)) { items.add(ti); vals.remove(bean); if (vals.isEmpty()) break; } } } return smodel == null ? items : IGNORED_VALUE; } @SuppressWarnings("unchecked") public Object coerceToBean(Object val, Component comp, BindContext ctx) { Set<Object> vals = new LinkedHashSet<Object>(); if (val != null) { final Tree tree = (Tree) comp; final TreeModel<?> model = tree.getModel(); if (model != null && !(model instanceof TreeSelectableModel)) { throw new UiException("model doesn't implement TreeSelectableModel"); } if (model != null) { int[][] paths = ((TreeSelectableModel) model).getSelectionPaths(); if (paths != null && paths.length > 0) { for (int[] path : paths) { vals.add(model.getChild(path)); } } } else { final Set<Treeitem> items = (Set<Treeitem>) Classes.coerce(LinkedHashSet.class, val); for (Treeitem item : items) { vals.add(item.getValue()); } } } return vals; } }