Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / debugger / command / ObjectModel.java
1 package jde.debugger.gui;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Comparator;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.TreeSet;
9 import javax.swing.tree.DefaultTreeModel;
10 import javax.swing.tree.MutableTreeNode;
11 import javax.swing.tree.TreeModel;
12 import javax.swing.tree.TreeNode;
13
14 import com.sun.jdi.Field;
15 import com.sun.jdi.ObjectReference;
16 import com.sun.jdi.ReferenceType;
17 import com.sun.jdi.StringReference;
18 import com.sun.jdi.Value;
19 import jde.debugger.JDEException;
20
21
22
23 /** A TreeNode for object references that aren't null or arrays.
24  * @author <a href="mailto:udalrich@carolingia.org">Troy Daniels</a>
25  * @since 2.3.2
26  * @version $Revision: 1.1 $
27  */
28 class ObjectModel extends ReferenceModel {
29   /**  Constructor
30    */
31   ObjectModel(ObjectReference value, DefaultTreeModel treeModel)  {
32     super();
33     if (null == value)
34       throw new IllegalArgumentException("Null value in constructor.");
35     if (null == treeModel)
36       throw new IllegalArgumentException("Null tree model in constructor.");
37     m_value = value;
38     m_treeModel = treeModel;
39   }
40
41
42   /** Get the number of children.
43    * @return The number of fields that we should be displaying.
44    */
45   int getChildCount() {
46     return getFields().size();
47   }
48   /** Returns if the node allows children */
49   boolean getAllowsChildren() { return true; }
50   /** Create a child at the given index.
51    * @return A tree node for the child at the given index */
52   MutableTreeNode createChildAt(int index) throws JDEException {
53     Field field = getFieldAt(index);
54     Value value = m_value.getValue(field);
55     MutableTreeNode node =
56         LVTreeNode.makeTreeNode(field, value, m_treeModel);
57     return node;
58   }
59
60   /** Get a string to represent the value of the variable */
61   String getValue() {
62     if (m_value instanceof StringReference) {
63       StringReference string = (StringReference) m_value;
64       return '"' + string.value() + '"';
65     } else {
66       return m_value.toString();
67     }
68   }
69
70   /** Get the fields that we wish to display */
71   private List getFields() {
72     ReferenceType refType = (ReferenceType) m_value.type();
73     Collection fields = new TreeSet(new Comparator() {
74         public int compare(Object o1, Object o2) {
75           Field field1 = (Field) o1;
76           Field field2 = (Field) o2;
77           return field1.name().compareTo(field2.name());
78         }
79       });
80     fields.addAll(refType.visibleFields());
81     return new ArrayList(fields);
82   }
83   /** Get the field that we wish to display
84    * @param index The index of the field
85    */
86   private Field getFieldAt(int index) {
87     return (Field) getFields().get(index);
88   }
89
90   /** Update the values in the children
91    * @param children The array of old child values
92    */
93   void updateChildren(TreeNode[] children) {
94     // For the children that already exist, set the new value.
95     //
96     // If the field name has changed, then this is an entirely
97     // different field and we need to create a new node.
98     TreeNode reloadParent = null;
99     int index = 0;
100     List fields = getFields();
101     for (Iterator iter = getFields().iterator();
102          iter.hasNext() && (index < children.length);
103          ++index) {
104       Field field = (Field) iter.next();
105       LVTreeNode node = asLVTreeNode(children[index]);
106       if ((null != node) &&
107           (node.getName().equals(field.name()))) {
108         // Match found.  Update the child.
109         node.setValue(m_value.getValue(field));
110       } else {
111         // Different node.  Reset it
112         if ((null != children[index]) &&
113             (null != children[index].getParent()))
114           reloadParent = children[index].getParent();
115         children[index] = null;
116       }
117     } // for each field
118
119     // Reload the model if we had significant changes
120     if (null != reloadParent)
121       m_treeModel.reload(reloadParent);
122   }
123
124
125   public String toString() {
126     return getClass().getName() + "[" +
127       "m_value=" + m_value + "," +
128       "m_treeModel=" + m_treeModel + "]";
129   }
130
131   private final ObjectReference m_value;
132   private final DefaultTreeModel m_treeModel;
133 }