KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > gui > TableModel


1 /*
2   Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com>
3   
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.aspects.gui;
19
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Vector;
26 import javax.swing.table.AbstractTableModel;
27 import org.apache.log4j.Logger;
28 import org.objectweb.jac.core.Collaboration;
29 import org.objectweb.jac.core.Wrappee;
30 import org.objectweb.jac.core.rtti.ClassItem;
31 import org.objectweb.jac.core.rtti.ClassRepository;
32 import org.objectweb.jac.core.rtti.CollectionItem;
33 import org.objectweb.jac.core.rtti.FieldItem;
34 import org.objectweb.jac.core.rtti.MemberItem;
35 import org.objectweb.jac.core.rtti.MetaItem;
36 import org.objectweb.jac.core.rtti.MethodItem;
37 import org.objectweb.jac.core.rtti.RttiAC;
38 import org.objectweb.jac.util.Classes;
39 import org.objectweb.jac.util.Enum;
40 import org.objectweb.jac.util.ExtArrays;
41 import org.objectweb.jac.util.Stack;
42
43 /**
44  * The data model for tables. */

45
46 public class TableModel extends AbstractTableModel
47     implements ExtendedTableModel, ObjectUpdate, CollectionUpdate
48 {
49     static Logger logger = Logger.getLogger("gui.generic");
50     static Logger loggerTable = Logger.getLogger("gui.table");
51     static Logger loggerAssoc = Logger.getLogger("gui.events");
52     static Logger loggerEvents = Logger.getLogger("associations");
53     static Logger loggerReg = Logger.getLogger("gui.register");
54
55     List rows = new Vector();
56     List objects = new Vector();
57     String[] headers;
58     ClassItem[] classes;
59     MemberItem[] members;
60
61     CollectionItem collection;
62     Object substance;
63
64     CollectionItemView collectionView;
65
66     /**
67      * Creates a new table model.
68      *
69      * @param collection the substance collection
70      * @param substance the object that holds the collection
71      * @param factory the used view factory
72      */

73     public TableModel(CollectionItem collection,
74                       Object substance, String viewName,
75                       ViewFactory factory)
76     {
77         this.collection = collection;
78         this.substance = substance;
79         collectionView = GuiAC.getView(collection,viewName);
80
81         members = collectionView.getMembersOrder();
82         logger.debug("membersOrder : " +
83                   (members!=null?(Arrays.asList(members).toString()):"[]"));
84         if (members==null) {
85             ClassItem clit = collection.getComponentType();
86             if (clit!=null && !(collection.isMap() && !RttiAC.isIndex(collection))) {
87                 logger.debug("class : " + clit.getName());
88                 ObjectView objectView = GuiAC.getView(clit,viewName);
89                 if (members==null)
90                     members = objectView.getTableMembersOrder();
91                 logger.debug("class tableMembersOrder : " +
92                           (members!=null?(Arrays.asList(members)+""):""));
93                 if (members==null)
94                     members = (MemberItem[])objectView.getAttributesOrder();
95                 logger.debug("class attributesOrder : " +
96                           (members!=null?(Arrays.asList(members)+""):""));
97                 if (members==null)
98                     members = clit.getFields();
99             } else if (!RttiAC.isIndex(collection)) {
100                 members = new MemberItem[2];
101                 clit = ClassRepository.get().getClass(Map.Entry.class);
102                 members[0] = clit.getField("key");
103                 members[1] = clit.getField("value");
104             } else {
105                 members = new MemberItem[0];
106             }
107         }
108         logger.debug("columns : " + Arrays.asList(members));
109
110         FieldItem oppositeRole =
111             (FieldItem)Collaboration.get().getAttribute(GuiAC.OPPOSITE_ROLE);
112         if (oppositeRole instanceof CollectionItem) {
113             loggerAssoc.debug("Ignoring collection oppositeRole "+oppositeRole);
114             oppositeRole = null;
115         }
116
117         // Ensure that members contains no oppositeRole
118
MemberItem[] tmp = new MemberItem[members.length];
119         int j=0;
120         for(int i=0; i<members.length; i++) {
121             if (members[i]!=oppositeRole) {
122                 tmp[j] = members[i];
123                 j++;
124             }
125         }
126         members = new MemberItem[j];
127         System.arraycopy(tmp,0,members,0,j);
128
129         int nbColumns = members.length;
130         headers = new String[nbColumns];
131         classes = new ClassItem[nbColumns];
132
133         Stack context = GuiAC.getGraphicContext();
134         for (int i=0; i<nbColumns; i++) {
135             if (members[i] instanceof FieldItem) {
136                 headers[i] = GuiAC.getLabel(members[i],context);
137             }
138             classes[i] = members[i].getTypeItem();
139         }
140
141         buildData();
142         Utils.registerCollection(substance,collection,this);
143     }
144
145     public CollectionItem getCollection() {
146         return collection;
147     }
148
149     static class CellLocation {
150         int row;
151         int column;
152         public CellLocation(int row, int column) {
153             this.row = row;
154             this.column = column;
155         }
156     }
157
158     public Object getCellRenderer(View tableView, int column,
159                                   ViewFactory factory, DisplayContext context) {
160         return getCellRenderer(tableView,substance,
161                                members[column],headers[column],
162                                collectionView,
163                                factory,context);
164     }
165
166     public static Object getCellRenderer(View tableView,
167                                          Object substance,
168                                          MemberItem member,
169                                          String header,
170                                          CollectionItemView collectionView,
171                                          ViewFactory factory,
172                                          DisplayContext context)
173     {
174         if (member instanceof FieldItem) {
175             FieldItem field = (FieldItem)member;
176             Stack typeNames = new Stack();
177
178             if (field.isReference())
179                 typeNames.push("cell:Reference");
180             else if (field instanceof CollectionItem)
181                 typeNames.push("cell:List");
182             typeNames.push("cell:"+field.getTypeItem().getName());
183
184             MetaItem type = RttiAC.getFieldType(field);
185             if (type!=null)
186                 typeNames.push("cell:"+type.getName());
187
188             Enum enum = GuiAC.getEnum(field);
189             if (enum!=null)
190                 typeNames.push("cell:Enum");
191
192             if (collectionView!=null) {
193                 String viewType = collectionView.getViewType(field);
194                 if (viewType!=null) {
195                     typeNames.push(viewType);
196                 }
197             }
198
199             loggerTable.debug("types for "+field+": "+typeNames);
200             while (!typeNames.empty()) {
201                 String typeName = (String)typeNames.pop();
202                 if (factory.hasViewerFor(typeName)) {
203                     try {
204                         FieldView cellViewer = (FieldView)factory.createView(
205                             "table["+field.getName()+"]",
206                             typeName,
207                             ExtArrays.emptyObjectArray,context);
208                         if (cellViewer instanceof TableCellViewer) {
209                             ((TableCellViewer)cellViewer).setTable(tableView);
210                         }
211                         loggerTable.debug("viewer = "+cellViewer);
212                         cellViewer.setField(field);
213                         return cellViewer;
214                     } catch (Exception e) {
215                         logger.error("Failed to instanciate TableCellRenderer "+
216                                      field.getName()+" for column "+header,
217                                      e);
218                     }
219                 } else {
220                     loggerTable.debug("no viewer found for type "+typeName);
221                 }
222             }
223         } else if (member instanceof MethodItem) {
224             MethodItem method = (MethodItem)member;
225             try {
226                 MethodView cellViewer = (MethodView)factory.createView(
227                     "table["+method.getName()+"]",
228                     "cell:Method",
229                     new Object[] {substance, method},context);
230                 if (cellViewer instanceof TableCellViewer) {
231                     ((TableCellViewer)cellViewer).setTable(tableView);
232                 }
233                 loggerTable.debug("viewer = "+cellViewer);
234                 return cellViewer;
235             } catch (Exception e) {
236                 logger.error("Failed to instanciate TableCellRenderer "+
237                              method.getName()+" for column "+header,
238                              e);
239             }
240         }
241         return null;
242     }
243
244     /**
245      * Populate the table model with the objects from the collection.
246      */

247     void buildData() {
248         Collection c = collection.getActualCollectionThroughAccessor(substance);
249         logger.debug("substance : " + substance);
250         logger.debug("objects : " + new Vector(c));
251         int nbColumns = members.length;
252         Iterator i = c.iterator();
253         int row = 0;
254         while (i.hasNext()) {
255             Object obj = i.next();
256             Object[] data = new Object[nbColumns];
257             if (obj!=null) {
258                 for (int j=0; j<nbColumns; j++) {
259                     try {
260                         if (members[j] instanceof FieldItem) {
261                             data[j] = ((FieldItem)members[j]).getThroughAccessor(obj);
262                             if (data[j] instanceof Wrappee && !(data[j] instanceof Collection)) {
263                                 Utils.registerObject(data[j],this,new CellLocation(row,j));
264                             }
265                         } else if (members[j] instanceof MethodItem) {
266                             data[j] = members[j].getName();
267                         }
268                     } catch (Exception e) {
269                         logger.error("Failed to build table cell for "+obj+"."+members[j].getName(),e);
270                     }
271                 }
272             }
273             logger.debug("add "+Arrays.asList(data));
274             addRow(obj,data);
275             row++;
276         }
277     }
278
279     public MemberItem[] getMembers() {
280         return members;
281     }
282
283     public String[] getHeaders() {
284         return headers;
285     }
286
287     /**
288      * Gets the column number of a field
289      */

290     public int getColumnIndex(FieldItem field) {
291         for (int i=0; i<members.length; i++) {
292             if (field==members[i])
293                 return i;
294         }
295         return -1;
296     }
297
298     public int getRowCount() {
299         return rows.size();
300     }
301     public int getColumnCount() {
302         return headers.length;
303     }
304
305     public String getColumnName(int column) {
306         return headers[column];
307     }
308     public Class getColumnClass(int column) {
309         loggerTable.debug("getColumnClass("+column+") -> "+classes[column].getName());
310         return Classes.getPrimitiveTypeWrapper(classes[column].getActualClass());
311     }
312     public Object getValueAt(int row, int column) {
313         loggerTable.debug("getValueAt("+row+","+column+") -> "+
314                   ((Object[])rows.get(row))[column]);
315         return ((Object[])rows.get(row))[column];
316     }
317     public Object getObject(int index) {
318         return objects.get(index);
319     }
320     public int indexOf(Object object) {
321         return objects.indexOf(object);
322     }
323     public Object getObject(int row, int col) {
324         return ((Object[])rows.get(row))[col];
325     }
326     public Object[] getRow(int row) {
327         return (Object[])rows.get(row);
328     }
329     public boolean isCellEditable(int row, int column) {
330         return false;
331     }
332
333     public void addRow(Object object, Object[] data) {
334         objects.add(object);
335         rows.add(data);
336         Utils.registerObject(object,this);
337     }
338
339     // ObjectUpdate interface
340
public void objectUpdated(Object substance,Object param) {
341         if (param==null) {
342             int index = objects.indexOf(substance);
343             if (index!=-1) {
344                 int nbColumns = getColumnCount();
345                 Object[] data = new Object[nbColumns];
346                 for (int j=0; j<nbColumns; j++) {
347                     if(members[j] instanceof FieldItem) {
348                         data[j] = ((FieldItem)members[j]).getThroughAccessor(substance);
349                     }
350                 }
351                 rows.set(index,data);
352             }
353             fireTableRowsUpdated(index,index);
354         } else {
355             CellLocation location = (CellLocation)param;
356             fireTableCellUpdated(location.row,location.column);
357         }
358     }
359
360     // CollectionUpdate
361
public void onChange(Object substance, CollectionItem collection,
362                          Object value, Object param) {
363         loggerEvents.debug("onChange "+substance+"."+collection);
364         unregisterViews();
365         int numRows = objects.size();
366         loggerEvents.debug(" numRows="+numRows);
367         objects.clear();
368         rows.clear();
369         if (numRows>0)
370             fireTableRowsDeleted(0,numRows-1);
371         buildData();
372         fireTableRowsInserted(0,objects.size()-1);
373     }
374
375     public void onAdd(Object substance, CollectionItem collection,
376                       Object value, Object added, Object param) {
377         loggerEvents.debug("onAdd "+substance+"."+collection);
378         // it's not that easy to optimize because we don't know the
379
// position of the added object
380
onChange(substance,collection,value,param);
381     }
382
383     public void onRemove(Object substance, CollectionItem collection,
384                          Object value, Object removed, Object param) {
385         loggerEvents.debug("onRemove "+substance+"."+collection);
386         onChange(substance,collection,value,param);
387     }
388
389     /**
390      * Register ourself as a view on all objects of the collection
391      */

392     protected void registerViews() {
393         loggerReg.debug("TableModel.registerViews "+objects.size());
394         Iterator i = objects.iterator();
395         while (i.hasNext()) {
396             Object object = i.next();
397             Utils.registerObject(object,this);
398         }
399     }
400
401     /**
402      * Unregister ourself as a view on all objects of the collection
403      */

404     protected void unregisterViews() {
405         loggerReg.debug("TableModel.unRegisterViews "+objects.size());
406         Iterator i = objects.iterator();
407         while (i.hasNext()) {
408             Object object = i.next();
409             Utils.unregisterObject(object,this);
410         }
411     }
412
413     public void close() {
414         unregisterViews();
415         Utils.unregisterCollection(substance,collection,this);
416     }
417
418     public TableFilter getFilter() {
419         return null;
420     }
421     public TableSorter getSorter() {
422         return null;
423     }
424 }
425
Popular Tags