KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > admin > common > PropertyTableModel


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.admin.common;
5
6 import java.lang.reflect.Method JavaDoc;
7 import java.util.ArrayList JavaDoc;
8 import java.util.HashMap JavaDoc;
9
10 import javax.swing.table.AbstractTableModel JavaDoc;
11
12 /**
13  * Displays an object's primitive properties in a PropertySheet-like way.
14  */

15
16 public class PropertyTableModel extends AbstractTableModel JavaDoc {
17   private Class JavaDoc
18     m_type;
19   
20   private Object JavaDoc
21     m_instance;
22
23   private String JavaDoc[]
24     m_fieldNames;
25
26   private String JavaDoc[]
27     m_headings;
28
29   protected Method JavaDoc
30     m_getters[];
31
32   protected Method JavaDoc
33     m_setters[];
34
35   protected Method JavaDoc
36     m_ops[];
37
38   protected static final HashMap JavaDoc
39     m_primitiveMap = new HashMap JavaDoc();
40
41   private static final String JavaDoc FIELD_HEADER = "Field";
42   private static final String JavaDoc VALUE_HEADER = "Value";
43
44   public static final int FIELD_COLUMN = 0;
45   public static final int VALUE_COLUMN = 1;
46   public static final int COLUMN_COUNT = 2;
47
48   static {
49     m_primitiveMap.put(Double.TYPE, Double JavaDoc.class);
50     m_primitiveMap.put(Integer.TYPE, Integer JavaDoc.class);
51     m_primitiveMap.put(Boolean.TYPE, Boolean JavaDoc.class);
52     m_primitiveMap.put(Character.TYPE, Character JavaDoc.class);
53     m_primitiveMap.put(Byte.TYPE, Byte JavaDoc.class);
54     m_primitiveMap.put(Float.TYPE, Float JavaDoc.class);
55     m_primitiveMap.put(Long.TYPE, Long JavaDoc.class);
56   }
57   
58   public PropertyTableModel() {
59     super();
60   }
61   
62   public PropertyTableModel(Object JavaDoc instance) {
63     this(instance, null, null);
64   }
65
66   public PropertyTableModel(Object JavaDoc instance, String JavaDoc[] fields) {
67     this(instance, fields, null);
68   }
69
70   public PropertyTableModel(Class JavaDoc type) {
71     this(type, null, null);
72   }
73
74   public PropertyTableModel(Class JavaDoc type, String JavaDoc[] fields) {
75     this(type, fields, null);
76   }
77
78   public PropertyTableModel(
79     Object JavaDoc instance,
80     String JavaDoc[] fields,
81     String JavaDoc[] headings)
82   {
83     this(instance.getClass(), fields, headings);
84     setInstance(instance);
85   }
86
87   public PropertyTableModel(
88     Class JavaDoc type,
89     String JavaDoc[] fields,
90     String JavaDoc[] headers)
91   {
92     super();
93     init(type, fields, headers);
94   }
95
96   public void setInstance(Object JavaDoc instance) {
97     m_instance = instance;
98     fireTableDataChanged();
99   }
100
101   public Object JavaDoc getInstance() {
102     return m_instance;
103   }
104   
105   public void init(
106     Class JavaDoc type,
107     String JavaDoc[] fields,
108     String JavaDoc[] headings)
109   {
110     m_type = type;
111     m_fieldNames = determineFields(fields);
112     m_headings = determineHeadings(headings);
113
114     setup();
115   }
116   
117   public void setup() {
118     if(m_type != null) {
119       int size = m_fieldNames.length;
120
121       m_setters = new Method JavaDoc[size];
122       m_getters = new Method JavaDoc[size];
123       m_ops = new Method JavaDoc[size];
124
125       for(int i = 0; i < m_fieldNames.length; i++) {
126         determineMethods(i, m_fieldNames[i]);
127       }
128     }
129   }
130
131   private Class JavaDoc _mapPrimitive(Class JavaDoc c) {
132     return (Class JavaDoc)m_primitiveMap.get(c);
133   }
134
135   /**
136    * If fieldNames == null, determine the set of primitive setters
137    * and construct a "fieldName" from the method name:
138    * void setMyCoolInteger(int) --> MyCoolInteger
139    */

140   private String JavaDoc[] determineFields(String JavaDoc fieldNames[]) {
141     if(fieldNames == null) {
142       if(m_type != null) {
143         Method JavaDoc method;
144         Method JavaDoc[] methods = m_type.getMethods();
145         ArrayList JavaDoc fieldList = new ArrayList JavaDoc();
146         String JavaDoc methodName;
147         Class JavaDoc returnType;
148         Class JavaDoc[] paramTypes;
149         
150         for(int i = 0; i < methods.length; i++) {
151           method = methods[i];
152           returnType = method.getReturnType();
153           paramTypes = method.getParameterTypes();
154           methodName = method.getName();
155
156           if(paramTypes.length == 0 &&
157              (methodName.startsWith("get") || methodName.startsWith("is")) &&
158              (returnType.isPrimitive() ||
159               returnType.equals(String JavaDoc.class) ||
160               returnType.equals(java.util.Date JavaDoc.class) ||
161               hasEditor(returnType)))
162           {
163             int j = 0;
164               
165             while(!Character.isUpperCase(methodName.charAt(j))) j++;
166             fieldList.add(methodName.substring(j));
167           }
168           else if(paramTypes.length == 0 && returnType == Void.TYPE) {
169             fieldList.add(methodName);
170           }
171         }
172         
173         fieldNames = (String JavaDoc[])fieldList.toArray(new String JavaDoc[]{});
174       }
175     }
176     
177     return fieldNames;
178   }
179   
180   /**
181    * Convert a Class field name to a reasonable display form:
182    * int myCoolInteger --> My cool integer
183    */

184   private static String JavaDoc fieldName2Heading(String JavaDoc fieldName) {
185     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
186     int len = fieldName.length();
187     char c;
188     
189     sb.append(Character.toUpperCase(fieldName.charAt(0)));
190     
191     for(int i = 1; i < len; i++) {
192       c = fieldName.charAt(i);
193       
194       if(Character.isUpperCase(c)) {
195         sb.append(" ");
196         sb.append(Character.toLowerCase(c));
197       }
198       else {
199         sb.append(c);
200       }
201     }
202
203     return sb.toString();
204   }
205   
206   private String JavaDoc[] determineHeadings(String JavaDoc headings[]) {
207     if(headings == null) {
208       ArrayList JavaDoc headingList = new ArrayList JavaDoc();
209       
210       for(int i = 0; i < m_fieldNames.length; i++) {
211         headingList.add(fieldName2Heading(m_fieldNames[i]));
212       }
213
214       headings = (String JavaDoc[])headingList.toArray(new String JavaDoc[]{});
215     }
216     
217     return headings;
218   }
219     
220   private void determineMethods(int index, String JavaDoc name) {
221     Method JavaDoc[] methods = m_type.getMethods();
222     Method JavaDoc method;
223     String JavaDoc methodName;
224     Class JavaDoc returnType;
225     Class JavaDoc[] paramTypes;
226
227     for(int i = 0; i < methods.length; i++) {
228       method = methods[i];
229       returnType = method.getReturnType();
230       paramTypes = method.getParameterTypes();
231       methodName = method.getName();
232
233       if(("set"+name).equals(methodName) &&
234          paramTypes.length == 1 &&
235          (paramTypes[0].isPrimitive() ||
236           paramTypes[0].equals(String JavaDoc.class) ||
237           paramTypes[0].equals(java.util.Date JavaDoc.class) ||
238           hasEditor(paramTypes[0])))
239       {
240         m_setters[index] = method;
241         break;
242       }
243     }
244
245     for(int i = 0; i < methods.length; i++) {
246       method = methods[i];
247       returnType = method.getReturnType();
248       paramTypes = method.getParameterTypes();
249       methodName = method.getName();
250
251       if((("get"+name).equals(methodName) ||
252           ("is"+name).equals(methodName)) &&
253           paramTypes.length == 0 &&
254           (returnType.isPrimitive() ||
255            returnType.equals(String JavaDoc.class) ||
256            returnType.equals(java.util.Date JavaDoc.class) ||
257            hasEditor(returnType)))
258       {
259         m_getters[index] = method;
260         break;
261       }
262     }
263
264     for(int i = 0; i < methods.length; i++) {
265       method = methods[i];
266       methodName = method.getName();
267
268       if(name.equals(methodName)) {
269         m_ops[index] = method;
270         break;
271       }
272     }
273   }
274
275   public int getRowCount() {
276     return m_instance != null ? m_fieldNames.length : 0;
277   }
278
279   public int getColumnCount() {
280     return COLUMN_COUNT;
281   }
282
283   public boolean isCellEditable(int row, int col) {
284     return (m_setters[row] != null) || (m_ops[row] != null);
285   }
286
287   public String JavaDoc getColumnName(int col) {
288     switch(col) {
289       case FIELD_COLUMN: return FIELD_HEADER;
290       case VALUE_COLUMN: return VALUE_HEADER;
291     }
292
293     return "PropertyTableModel: invalid column: "+col;
294   }
295
296   public Class JavaDoc getColumnClass(int col) {
297     return Object JavaDoc.class;
298   }
299
300   public Class JavaDoc getRowClass(int row) {
301     Method JavaDoc method = m_getters[row];
302
303     if(method != null) {
304       Class JavaDoc rowClass = method.getReturnType();
305
306       if(rowClass.isPrimitive()) {
307         rowClass = _mapPrimitive(rowClass);
308       }
309
310       return rowClass;
311     }
312
313     if((method = m_ops[row]) != null) {
314       return Method JavaDoc.class;
315     }
316
317     return Object JavaDoc.class;
318   }
319   
320   private Object JavaDoc _getFieldValue(int fieldIndex) {
321     try {
322       return m_getters[fieldIndex].invoke(m_instance, new Object JavaDoc[] {});
323     }
324     catch(Exception JavaDoc e) {
325       return e.getMessage();
326     }
327   }
328
329   public String JavaDoc getFieldHeading(int row) {
330     return m_headings[row] != null ?
331            m_headings[row] : m_fieldNames[row];
332   }
333   
334   public Object JavaDoc getValueAt(int row, int col) {
335     switch(col) {
336       case FIELD_COLUMN: {
337         return getFieldHeading(row);
338       }
339       case VALUE_COLUMN: {
340         if(m_instance != null) {
341           Method JavaDoc method;
342           
343           if((method = m_ops[row]) != null) {
344             return method;
345           }
346           else {
347             return _getFieldValue(row);
348           }
349         }
350       }
351     }
352
353     return "";
354   }
355
356   public void setValueAt(Object JavaDoc value, int row, int col) {
357     Method JavaDoc setter = m_setters[col];
358
359     if(setter != null) {
360       try {
361         setter.invoke(getValueAt(row, col), new Object JavaDoc[] {value});
362       }
363       catch(Exception JavaDoc e) {/*ignore*/}
364     }
365   }
366
367   public void clear() {
368     setInstance(null);
369   }
370
371   public boolean hasEditor(Class JavaDoc type) {
372     return false;
373   }
374 }
375
Popular Tags