1 /*
2 * Angkor Web Framework
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */
7
8 package com.tirsen.angkor.beans;
9
10 import com.tirsen.angkor.table.AbstractTableModel;
11 import com.tirsen.angkor.widget.ValueModel;
12
13 import java.beans.BeanInfo;
14 import java.beans.IntrospectionException;
15 import java.beans.Introspector;
16 import java.beans.PropertyDescriptor;
17 import java.io.Serializable;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
23
24 public class JavaBeanTableModel extends AbstractTableModel
25 {
26 private Class rowClass;
27 private List rows;
28 private List columns;
29
30 public JavaBeanTableModel()
31 {
32 }
33
34 public JavaBeanTableModel(Class rowClass)
35 {
36 this.rowClass = rowClass;
37 }
38
39 public interface TableColumnModel extends Serializable
40 {
41 String getName();
42
43 ValueModel getValue(Object row);
44 }
45
46 private static class PropertyTableColumnModel implements TableColumnModel
47 {
48 private String name;
49 private transient PropertyDescriptor property;
50
51 public PropertyTableColumnModel(PropertyDescriptor property)
52 {
53 this.property = property;
54 }
55
56 public PropertyTableColumnModel(String name, PropertyDescriptor property)
57 {
58 this.name = name;
59 this.property = property;
60 }
61
62 public String getName()
63 {
64 return name == null ? property.getDisplayName() : name;
65 }
66
67 public ValueModel getValue(Object row)
68 {
69 return new PropertyValueModel(row, property);
70 }
71 }
72
73 /***
74 * Resets the columns.
75 */
76 public void resetColumns()
77 {
78 columns = null;
79 }
80
81 /***
82 * If the columns are not already created creates columns based on all the properties in the beans.
83 */
84 private void createDefaultColumns()
85 {
86 if (columns == null)
87 {
88 try
89 {
90 PropertyDescriptor[] properties = getProperties();
91 columns = new ArrayList(properties.length);
92 for (int i = 0; i < properties.length; i++)
93 {
94 PropertyDescriptor property = properties[i];
95 addColumn(new PropertyTableColumnModel(property));
96 }
97 }
98 catch (IntrospectionException e)
99 {
100 throw new RuntimeException(e.getMessage());
101 }
102 }
103 }
104
105 private PropertyDescriptor[] getProperties() throws IntrospectionException
106 {
107 Class beanClass = getRowClass();
108 BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);
109 PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
110 return properties;
111 }
112
113 private Class getRowClass()
114 {
115 Class cls = rowClass;
116 if (cls == null && getRowCount() > 0) cls = getRow(0).getClass();
117 if (cls == null) cls = getRows().getClass().getComponentType();
118 if (cls == null) throw new IllegalStateException("Could not determine class of objects used for rows.");
119 return cls;
120 }
121
122 public void addColumn(TableColumnModel column)
123 {
124 columns.add(column);
125 }
126
127 public PropertyDescriptor findProperty(String property)
128 {
129 try
130 {
131 PropertyDescriptor[] properties = getProperties();
132 for (int i = 0; i < properties.length; i++)
133 {
134 PropertyDescriptor propertyDesc = properties[i];
135 if (propertyDesc.getName().equals(property)) return propertyDesc;
136 }
137 throw new IntrospectionException("No such property " + property);
138 }
139 catch (IntrospectionException e)
140 {
141 throw new RuntimeException(e.getMessage());
142 }
143 }
144
145 public void addColumn(String name, String property)
146 {
147 if (columns == null) columns = new ArrayList(1);
148 columns.add(new PropertyTableColumnModel(name, findProperty(property)));
149 }
150
151 public String getColumnName(int column)
152 {
153 return getColumn(column).getName();
154 }
155
156 public int getColumnCount()
157 {
158 createDefaultColumns();
159 return columns.size();
160 }
161
162 public ValueModel getValueAt(int row, int column)
163 {
164 return (getColumn(column)).getValue(getRow(row));
165 }
166
167 private TableColumnModel getColumn(int column)
168 {
169 createDefaultColumns();
170 return (TableColumnModel) columns.get(column);
171 }
172
173 /***
174 * Gets the value object for a specified row, also checks wheather row is within range specified by
175 * {@link #setRange(int,int)}.
176 * @throws IllegalArgumentException if <code>row</code> parameter is outside specified range.
177 */
178 public Object getRow(int row)
179 {
180 if (row < getStart() || row > getEnd())
181 {
182 throw new IllegalArgumentException("Tried to access row " + row +
183 " outside range (" + getStart() + ", " + getEnd() + ").");
184 }
185 return getRows().get(row);
186 }
187
188 private List getRows()
189 {
190 if (rows == null) throw new IllegalStateException("Tried to access model before initializing rows.");
191 return rows;
192 }
193
194 public int getRowCount()
195 {
196 int rowCount = super.getRowCount();
197 if (rowCount == -1)
198 {
199 if (rows == null)
200 rowCount = 0;
201 else
202 rowCount = getRows().size();
203 }
204 return rowCount;
205 }
206
207 public void setRow(int row, Object object)
208 {
209 ensureCapable(row);
210 rows.set(row, object);
211 }
212
213 /***
214 * Sets a segment of rows starting at specified startRow.
215 */
216 public void setRows(int startRow, Collection objects)
217 {
218 ensureCapable(startRow + objects.size());
219 int row = startRow;
220 for (Iterator iterator = objects.iterator(); iterator.hasNext();)
221 {
222 Object o = (Object) iterator.next();
223 rows.set(row++, o);
224 }
225 }
226
227 private void ensureCapable(int row)
228 {
229 if (rows == null) rows = new ArrayList(row);
230 int size = rows.size();
231 for (int i = size - row; i < size + 1; i++)
232 {
233 rows.add(null);
234 }
235 }
236
237 public void setRows(Object[] rows)
238 {
239 if (rows != null)
240 this.rows = Arrays.asList(rows);
241 else
242 this.rows = null;
243 }
244
245 public void setRows(List rows)
246 {
247 this.rows = new ArrayList(rows);
248 }
249
250 public void setRows(Iterator iterator)
251 {
252 rows = new ArrayList();
253 while (iterator.hasNext())
254 {
255 Object o = (Object) iterator.next();
256 rows.add(o);
257 }
258 }
259
260 public void empty()
261 {
262 super.empty();
263 rows = null;
264 }
265 }
This page was automatically generated by Maven