View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.river.example.browser;
19  
20  import java.lang.reflect.Field;
21  import javax.swing.tree.TreeModel;
22  import javax.swing.tree.TreePath;
23  import javax.swing.tree.DefaultTreeModel;
24  import javax.swing.tree.DefaultMutableTreeNode;
25  import javax.swing.Icon;
26  
27  /**
28   *
29   * @author Sun Microsystems, Inc.
30   *
31   * @version 0.2 06/04/98
32   *
33   */
34  class ObjectNode extends DefaultMutableTreeNode implements java.io.Serializable {
35  
36    // "classname", "classname fieldName" or "classname fieldName=value"
37    /**
38     * @serial
39     */
40    private String name;
41  
42    /**
43     * @serial
44     */
45    private Object obj;
46  
47    /**
48     * @serial
49     */
50    private Class clazz;
51  
52    /**
53     * @serial
54     */
55    private String fieldName;
56  
57    /**
58     * @serial
59     */
60    private int arrayIndex = -1;
61  
62    /**
63     * @serial
64     */
65    private boolean editable = false;
66  
67    /**
68     * @serial
69     */
70    private boolean isLeaf;
71  
72    /**
73     * @serial
74     */
75    private boolean isAdministrable;	// root level
76  
77    /**
78     * @serial
79     */
80    private boolean isControllable;	// entry level
81  
82    /**
83     * @serial
84     */
85    private boolean isRoot = false;
86  
87    /**
88     * @serial
89     */
90    private boolean isEntryTop = false;
91  
92    // icons
93    private static Icon[] icons = new Icon[6];
94    static {
95      icons[0] = MetalIcons.getBlueFolderIcon();	// Administrable Service, Controllable Attribute
96      icons[1] = MetalIcons.getGrayFolderIcon();	// Non-administrable Service
97      icons[2] = MetalIcons.getOrangeFolderIcon();	// Uncontrollable Attribute
98      icons[3] = MetalIcons.getBlueFileIcon();	// Administrable Service, Controllable Attribute
99      icons[4] = MetalIcons.getGrayFileIcon();	// Non-administrable Service
100     icons[5] = MetalIcons.getOrangeFileIcon();	// Uncontrollable Attribute
101   }
102 
103   /**
104      Constructor for a root node.
105   */
106   public ObjectNode(boolean isAdministrable) {
107     this("Root node", "".getClass(), null, -1, false);
108 
109     this.isAdministrable = isAdministrable;
110     this.isRoot = true;
111     this.isEntryTop = true;
112   }
113 
114   /**
115      Constructor for an entry (attribute) top nodes.
116   */
117   public ObjectNode(Object obj, boolean isControllable) {
118     this(obj, obj.getClass(), null, -1, false);
119 
120     this.isControllable = isControllable;
121     this.isEntryTop = true;
122   }
123 
124   /**
125      Constructor for an ordinary field.
126   */
127   public ObjectNode(Object obj, Class clazz, String fieldName, boolean isLeaf) {
128     this(obj, clazz, fieldName, -1, isLeaf);
129   }
130 
131   /**
132      Constructor for an array element.
133   */
134   public ObjectNode(Object obj, Class clazz, String fieldName, int arrayIndex, boolean isLeaf) {
135     this.obj = obj;
136     this.clazz = clazz;
137     this.fieldName = fieldName;
138     this.arrayIndex = arrayIndex;
139     this.isLeaf = isLeaf;
140 
141     super.setAllowsChildren(! isLeaf);
142     setNodeName();
143   }
144 
145   private void setNodeName() {
146     name = Introspector.getTypename(clazz, false);
147     if(fieldName != null)
148       name += " " + fieldName;
149 
150     if(isLeaf) {
151       //Class clazz = obj.getClass();
152       String value = "";
153       if(arrayIndex >= 0)
154 	value += ("[" + arrayIndex + "]");
155       value += "=";
156       if(clazz.isPrimitive()){
157 	value += "" + obj;
158 	editable = false;
159       } else if(Introspector.isWrapper(clazz)){
160 	// Wrapper objects
161 	value += "" + obj;
162 	editable = true;
163       } else if(Introspector.isString(clazz)) {
164 	value += "\"" + obj + "\"";
165 	editable = true;
166       } else {
167 	value += (obj == null ? "null" : obj.toString());
168       }
169       name += value;
170     } else if(obj == null) {
171       name += "=null";
172     }
173 
174     super.setUserObject(name);
175   }
176 
177   public void add(ObjectNode child){
178     child.setAdministrable(isAdministrable);
179     if(! isRoot){
180       child.setControllable(isControllable);
181     }
182 
183     super.add(child);
184   }
185 
186   public Object getEntryTop() {
187     ObjectNode snode = this;
188     do {
189       snode = (ObjectNode) snode.getParent();
190     } while(! snode.isEntryTop());
191 
192     return snode.getObject();
193   }
194 
195   protected boolean isEntryTop() {
196     return isEntryTop;
197   }
198 
199   public void setObjectRecursive() throws NoSuchFieldException, IllegalAccessException {
200     ObjectNode pnode = this;
201     do {
202       pnode = (ObjectNode) pnode.getParent();
203       Object pobj = pnode.getObject();
204       // Needs to think about array modifications
205       Field f = pobj.getClass().getField(fieldName);
206       f.set(pobj, obj);
207     } while(! pnode.isEntryTop());
208   }
209 
210   public String getTitle() {
211     return name;
212   }
213 
214   public Icon getIcon() {
215     /*
216       if(isAdministrable){
217       if(isControllable){
218       if(isLeaf)	    return icons[3];
219       else		    return icons[0];
220       } else {
221       if(isLeaf)	    return icons[5];
222       else		    return icons[2];
223       }
224       } else {
225       if(isLeaf)	    return icons[4];
226       else		    return icons[1];
227       }
228     */
229     if(isAdministrable && isControllable)
230       if(isLeaf)	return icons[3];
231       else		return icons[0];
232     else
233       if(isLeaf)	return icons[4];
234       else		return icons[1];
235   }
236 
237 
238   // Overwrite
239   public void setUserObject(Object obj){
240     if(obj instanceof String)
241       name = (String) obj;
242 
243     super.setUserObject(obj);
244   }
245 
246   public Object getUserObject(){
247     return name;
248   }
249 
250   public String toString() {
251     return name;
252   }
253 
254   public String getFieldName() {
255     return fieldName;
256   }
257 
258   public Object getObject() {
259     return obj;
260   }
261 
262   public boolean isEditable() {
263     return editable;
264   }
265 
266   public boolean isAdministrable() {
267     return isAdministrable;
268   }
269 
270   public void setAdministrable(boolean val) {
271     isAdministrable = val;
272   }
273 
274   public boolean isControllable() {
275     return isControllable;
276   }
277 
278   public void setControllable(boolean val) {
279     isControllable = val;
280   }
281 
282   public Object setValue(Object val) throws NumberFormatException {
283     String clazzName = clazz.getName();
284     Object newObj = null;
285 
286     if(val instanceof String || val == null) {
287       String sval = (String) val;
288       if(clazzName.equals("java.lang.Integer"))
289 	newObj = Integer.valueOf(sval);
290       else if(clazzName.equals("java.lang.Boolean"))
291 	newObj = Boolean.valueOf(sval);
292       else if(clazzName.equals("java.lang.Byte"))
293 	newObj = Byte.valueOf(sval);
294       else if(clazzName.equals("java.lang.Character"))
295 	newObj = Character.valueOf(sval.charAt(0));
296       else if(clazzName.equals("java.lang.Double"))
297 	newObj = Double.valueOf(sval);
298       else if(clazzName.equals("java.lang.Float"))
299 	newObj = Float.valueOf(sval);
300       else if(clazzName.equals("java.lang.Long"))
301 	newObj = Long.valueOf(sval);
302       else if(clazzName.equals("java.lang.String"))
303 	newObj = sval;	// clone WHY?
304     } else if(val.getClass().equals(obj.getClass())) {
305       // same class type
306       newObj = val;
307     }
308 
309     Object oldObj = obj;
310     obj = newObj;
311 
312     setNodeName();
313 
314     return oldObj;
315   }
316 }