/* 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;
}
}