/* * NameValueTreeModel.java * * Created on July 31, 2007, 11:45 AM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.autoplot.metatree; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import org.das2.qds.QDataSet; import org.das2.qds.util.PropertiesTreeModel; /** * * @author jbf */ public class NameValueTreeModel implements TreeModel { final Object root; List nodes; public interface TreeNode { int childCount(); Object getChild(int i); boolean isLeaf(); String toString(); } static class StringPropertyNode implements TreeNode { private static final int LINE_LEN = 133; String name; String value; List splits; boolean hasKids; StringPropertyNode(String name, String value) { this.name = name; value= value.trim(); this.value = value; if ( value.length()>LINE_LEN || value.contains("\n") ) { splits= new ArrayList<>(); int ii=0; while ( iiLINE_LEN || i==-1 ) { if ( value.length()-ii < LINE_LEN ) { ii= value.length(); } else { i= value.lastIndexOf(' ',ii+LINE_LEN); if ( i==-1 ) { ii= ii+LINE_LEN; } else if ( i>ii ) { ii= i+1; } else { ii= value.length(); // couldn't find a break } } } else { ii= i+1; } if ( ii value) { this.name = name; this.value = value; this.keys= (String[]) this.value.keySet().toArray( new String[ value.size() ] ); this.hasKids = this.keys.length>0; } public String toString() { return "" + name ; } public int childCount() { return value.size(); } public Object getChild(int i) { String key= keys[i]; return createNode( key, value.get(key) ); } public boolean isLeaf() { return !hasKids; } } static class TreeNodeAdapter implements TreeNode { javax.swing.tree.TreeNode node; String name; TreeNodeAdapter( String name, javax.swing.tree.TreeNode node ) { this.node= node; this.name= name; } public int childCount() { return node.getChildCount(); } public Object getChild(int i) { return new TreeNodeAdapter( null, node.getChildAt(i) ); } public boolean isLeaf() { return node.isLeaf(); } public String toString() { if ( name!=null ) { return name + "=" + node.toString(); } else { return node.toString(); } } } static Object createNode(String name, Object value) { if ( value==null ) { return new StringPropertyNode(name, "null" ); } else if (value.getClass().isArray()) { return new ArrayPropertyNode(name, value); } else if (value instanceof String) { String svalue= (String) value; if ( svalue.length()>800 ) { svalue= svalue.substring(0,797) + "..."; } return new StringPropertyNode(name, svalue); } else if (value instanceof Map) { return new MapPropertyNode(name, (Map) value); } else if (value instanceof QDataSet ) { PropertiesTreeModel model= new PropertiesTreeModel((QDataSet)value,100); return new TreeNodeAdapter( name, (javax.swing.tree.TreeNode)model.getRoot() ); } else { return new StringPropertyNode(name, String.valueOf(value)); } } public Object getRoot() { return root; } public Object getChild(Object parent, int index) { if (parent == root) { return nodes.get(index); } else { TreeNode p = (TreeNode) parent; return p.getChild(index); } } public int getChildCount(Object parent) { if (parent == root) { return nodes.size(); } else { TreeNode p = (TreeNode) parent; return p.childCount(); } } public boolean isLeaf(Object parent) { if (parent == root) { return false; } else if (parent instanceof TreeNode) { TreeNode p = (TreeNode) parent; return p.isLeaf(); } else { return true; } } public void valueForPathChanged(TreePath path, Object newValue) { } public int getIndexOfChild(Object parent, Object child) { return 0; } public void addTreeModelListener(TreeModelListener l) { } public void removeTreeModelListener(TreeModelListener l) { } /** Creates a new instance of NameValueTreeModel */ private NameValueTreeModel(Object root, List nodes) { this.nodes = nodes; this.root = root; } public static NameValueTreeModel create(Object root, List names, List values) { ArrayList nodes = new ArrayList(names.size()); for (int i = 0; i < names.size(); i++) { nodes.add(createNode((String) names.get(i), values.get(i))); } return new NameValueTreeModel(root, nodes); } /** * creates a new tree from a hash map. * @param root a node to use as the root. Often this will just be a string identifying the properties set like "metadata(cdf)" * @param map Map that are translated to nodes. Most value types result in =, while values that are * Maps may be handled recursively. * @return */ public static NameValueTreeModel create(Object root, Map map) { List nodes; if ( map!=null ) { nodes = new ArrayList(map.size()); for ( Iterator i = map.entrySet().iterator(); i.hasNext();) { Entry e= (Entry)i.next(); nodes.add( createNode( String.valueOf(e.getKey()), e.getValue() ) ); } } else { nodes= Collections.EMPTY_LIST; } return new NameValueTreeModel( root, nodes ); } public String toString() { return String.valueOf(this.root) + "(" + nodes.size() + "key/value pairs)"; } }