KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > sun > share > configbean > customizers > common > GenericTableModel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * GenericTableModel.java
21  *
22  * Created on October 7, 2003, 11:58 AM
23  */

24
25 package org.netbeans.modules.j2ee.sun.share.configbean.customizers.common;
26
27 import java.util.List JavaDoc;
28 import java.util.ResourceBundle JavaDoc;
29
30 import org.netbeans.modules.j2ee.sun.dd.api.CommonDDBean;
31 import org.netbeans.modules.j2ee.sun.share.configbean.ASDDVersion;
32
33
34 /** This is a messy class. My apologies, it should have been created on it's own,
35  * directly from the TableModel interface, but for some godforsaken reason I
36  * chose to derive it from BeanTableModel and I've been paying for it ever since.
37  *
38  * That, and our schema2beans can't or won't adhere to any reasonable standard
39  * when generating child properties and/or attributes.
40  *
41  * Proper design should have been Model interface wrapped around an embedded
42  * object to handle data storage in one of the three ways we handle it: (or
43  * alternatively, an abstract interchangable model with three derivatives.)
44  *
45  * (a) fields are child values and attributes of an owner CommonDDBean and
46  * that owner's parent owns a list of these beans. (SunWebApp.WebProperties)
47  * (b) Same as (a) except that the beans owner is a single bean that owns nothing
48  * else and is owned by a larger parent. (SunWebApp.JspConfig)
49  * (c) fields are child attributes (no values) of an owner CommonDDBean. The
50  * attributes are indexed within this bean, so there is no extra bean
51  * being created for each row. (SunWebApp.Cache.CacheMapping:KeyField)
52  *
53  *
54  * @author Peter Williams
55  * @version %I%, %G%
56  */

57 public class GenericTableModel extends BeanTableModel {
58
59     private String JavaDoc parentPropertyName;
60     private ParentPropertyFactory parentPropertyFactory;
61     private boolean indexedChildren;
62     private int keyIndex;
63
64     private List JavaDoc properties;
65     private String JavaDoc [] columnNames;
66
67     private ASDDVersion appServerVersion;
68     
69     /** Use this constructor when there is not going to be a parent CommonDDBean for
70      * rows to be added to as they are created (and thus parent property name
71      * for the items stored in the table.) For example, several BaseBeans store
72      * an array of items instead of having a single property that contains the array.
73      *
74      * @param ppc The class name of the CommonDDBean that represents a row in the table
75      * @param p The list of table entry objects. This determines the columns in
76      * the table and provides the appropriate set/get code for each value
77      */

78     public GenericTableModel(ParentPropertyFactory ppf, List JavaDoc p) {
79         this(null, ppf, p, false, 0);
80     }
81
82     /** Use this constructor when there is a parent basebean that will own all the
83      * rows as properties. Some BaseBeans own a property, which in turn owns
84      * another property that forms the rows in the table. In this case, the model
85      * can add the rows to an instance of that middle property as the rows are
86      * created.
87      *
88      * @param ppn The property name that the parent CommonDDBean uses to represent
89      * the CommonDDBean that stores each row.
90      * @param ppc The class name of the CommonDDBean that represents a row in the table
91      * @param p The list of table entry objects. This determines the columns in
92      * the table and provides the appropriate set/get code for each value
93      */

94     public GenericTableModel(String JavaDoc ppn, ParentPropertyFactory ppf, List JavaDoc p) {
95         this(ppn, ppf, p, false, 0);
96     }
97
98     /** Use this constructor when there isn't a child bean. If all parameters
99      * in the table are attributes, then schema2beans doesn't generate a child
100      * bean to hold them, it tacks them on all as indexed attributes of a single
101      * parent bean. See CacheMapping.KeyField and ConstraintField.ConstraintFieldValue
102      * for examples of this.
103      *
104      */

105     public GenericTableModel(String JavaDoc ppn, List JavaDoc p) {
106         this(ppn, null, p, true, 0);
107     }
108
109     /** Use this constructor when the key field to check to prevent duplication
110      * is not field 0. Currently uses string equality based on the results of
111      * toString() on the field. Does not support keys spanning multiple columns.
112      *
113      * @param ppn The property name that the parent CommonDDBean uses to represent
114      * the CommonDDBean that stores each row.
115      * @param ppc The class name of the CommonDDBean that represents a row in the table
116      * @param p The list of table entry objects. This determines the columns in
117      * the table and provides the appropriate set/get code for each value
118      * @param key The field index that represents the key field. Use -1 to indicate
119      * duplicates are ok, otherwise use an integer from 0 to "columns-1" to
120      * indicate which field value to check.
121      */

122     public GenericTableModel(String JavaDoc ppn, ParentPropertyFactory ppf, List JavaDoc p, boolean indexed, int key) {
123         parentPropertyName = ppn;
124         parentPropertyFactory = ppf;
125         properties = p;
126         indexedChildren = indexed;
127         keyIndex = key;
128
129         columnNames = new String JavaDoc [p.size()];
130         for(int i = 0; i < properties.size(); i++) {
131             columnNames[i] = ((TableEntry) properties.get(i)).getColumnName();
132         }
133     }
134
135     /** Initialize the model based on the contents of the parent bean.
136      * This method is for models that specified a parent property name during
137      * construction.
138      *
139      * @param parent The parent base bean that is storing the properties. The
140      * properties are expected to be stored under the property name specified
141      * by the constructor parameter 'parentPropertyName' which means you must
142      * use that variant for this method to make sense.
143      */

144     public void setData(CommonDDBean parent, ASDDVersion asVersion) {
145         assert asVersion != null : "Application Server version cannot be null!!!";
146         appServerVersion = asVersion;
147         
148         if(parentPropertyName != null) {
149             CommonDDBean [] children = (CommonDDBean []) parent.getValues(parentPropertyName);
150             setData(parent, children);
151         }
152     }
153
154     /** Initialize the model from the list of objects passed in. The items in
155      * the list are expected to be instances of the property class specified in
156      * the constructor.
157      *
158      * @param rows Generally this method is used when there is no parent CommonDDBean,
159      * though that is not required. What is required is that all objects
160      * in the List are castable to the class type that is created by the factory
161      * method in the instance of ParentPropertyFactory passed in.
162      */

163     public void setData(List JavaDoc rows, ASDDVersion asVersion) {
164         assert asVersion != null : "Application Server version cannot be null!!!";
165         appServerVersion = asVersion;
166         
167         CommonDDBean [] children = null;
168
169         if(rows != null) {
170             children = (CommonDDBean []) rows.toArray(new CommonDDBean[0]);
171         }
172
173         setData(null, children);
174     }
175
176     /** Initialize the model from the array of CommonDDBeans passed in. The items in
177      * the array are expected to be instances of the property class specified in
178      * the constructor.
179      *
180      * @param rows Generally this method is used when there is no parent CommonDDBean,
181      * though that is not required. What is required is that all objects
182      * in the List are castable to the class type that is created by the factory
183      * method in the instance of ParentPropertyFactory passed in.
184      */

185     public void setData(CommonDDBean [] rows, ASDDVersion asVersion) {
186         assert asVersion != null : "Application Server version cannot be null!!!";
187         appServerVersion = asVersion;
188         
189         CommonDDBean [] children = null;
190
191         if(rows != null && rows.length > 0) {
192             children = new CommonDDBean [rows.length];
193             System.arraycopy(rows, 0, children, 0, rows.length);
194         }
195
196         setData(null, children);
197     }
198
199     /** Initialize the model from the parent property bean, but in this case,
200      * the parent is the actual owner of the list of properties because all
201      * the fields are attributes of the parent, not of a child bean. This
202      * method is for models that specified only a parent property name but
203      * no parent property class, so by definition the children are stored
204      * as indexed properties of the bean instance passed in here.
205      */

206     public void setDataBaseBean(CommonDDBean parent, ASDDVersion asVersion) {
207         assert asVersion != null : "Application Server version cannot be null!!!";
208         appServerVersion = asVersion;
209         
210         setData(parent, new CommonDDBean [0]);
211         fireTableDataChanged();
212     }
213
214     public List JavaDoc getData() {
215         return getChildren();
216     }
217
218     public CommonDDBean getDataBaseBean() {
219         CommonDDBean bbParent = null;
220
221         Object JavaDoc parent = getParent();
222         if(parent instanceof CommonDDBean) {
223             bbParent = (CommonDDBean) parent;
224         }
225
226         return bbParent;
227     }
228     
229     public ASDDVersion getAppServerVersion() {
230         return appServerVersion;
231     }
232
233     public int getRowCount() {
234         int result = super.getRowCount();
235
236         // If we are using the parent property object to hold the children, then
237
// this is the correct way to get the number of rows.
238
if(indexedChildren) {
239             CommonDDBean parent = (CommonDDBean) getParent();
240             // !PW I found this getting called during initialization phase (when the
241
// parent has not been assigned yet.)
242
if(parent != null) {
243                 result = parent.size(parentPropertyName);
244             }
245         }
246
247         return result;
248     }
249
250     protected String JavaDoc[] getColumnNames() {
251         return columnNames;
252     }
253
254     protected List JavaDoc getPropertyDefinitions() {
255         return properties;
256     }
257
258     public Object JavaDoc getValueAt(int row, int column){
259         Object JavaDoc result = null;
260         TableEntry columnEntry = (TableEntry) properties.get(column);
261
262         if(indexedChildren) {
263             CommonDDBean parent = (CommonDDBean) getParent();
264 // result = parent.getAttributeValue(parentPropertyName, row, columnEntry.getPropertyName());
265
result = columnEntry.getEntry(parent, row);
266         } else {
267             CommonDDBean param = (CommonDDBean) getChildren().get(row);
268             if(param != null) {
269                 result = columnEntry.getEntry(param);
270             }
271         }
272
273         return result;
274     }
275
276     /** BeanTableModel Methods
277      */

278     public Object JavaDoc addRow(Object JavaDoc[] values) {
279         CommonDDBean param = null;
280
281         if(parentPropertyFactory != null) {
282             param = parentPropertyFactory.newParentProperty(appServerVersion);
283             for(int i = 0, max = properties.size(); i < max; i++) {
284                 ((TableEntry) properties.get(i)).setEntry(param, values[i]);
285             }
286             if(parentPropertyName != null) {
287                 ((CommonDDBean) getParent()).addValue(parentPropertyName, param);
288             }
289
290             getChildren().add(param);
291         } else if(indexedChildren) {
292             CommonDDBean parent = (CommonDDBean) getParent();
293             int newRow = parent.addValue(parentPropertyName, Boolean.TRUE);
294             for(int i = 0, max = properties.size(); i < max; i++) {
295                 TableEntry columnEntry = (TableEntry) properties.get(i);
296 // parent.setAttributeValue(parentPropertyName, newRow, columnEntry.getPropertyName(), (String) values[i]);
297
columnEntry.setEntry(parent, newRow, values[i]);
298             }
299         }
300                 
301         int rowChanged = getRowCount() - 1;
302         fireTableRowsInserted(rowChanged, rowChanged);
303
304         return param;
305     }
306
307     public void editRow(int row, Object JavaDoc[] values) {
308         if(indexedChildren) {
309             CommonDDBean parent = (CommonDDBean) getParent();
310             for(int i = 0, max = properties.size(); i < max; i++) {
311                 TableEntry columnEntry = (TableEntry) properties.get(i);
312 // parent.setAttributeValue(parentPropertyName, row, columnEntry.getPropertyName(), (String) values[i]);
313
columnEntry.setEntry(parent, row, values[i]);
314             }
315         } else {
316             CommonDDBean param = (CommonDDBean) getChildren().get(row);
317
318             if(param != null) {
319                 for(int i = 0; i < properties.size(); i++) {
320                     ((TableEntry) properties.get(i)).setEntry(param, values[i]);
321                 }
322             }
323         }
324
325         fireTableRowsUpdated(row, row);
326     }
327
328     public void removeRow(int row) {
329         CommonDDBean parent = (CommonDDBean) getParent();
330
331         if(indexedChildren) {
332             parent.removeValue(parentPropertyName, row);
333         } else {
334             List JavaDoc children = getChildren();
335
336             if(parentPropertyName != null) {
337                 parent.removeValue(parentPropertyName, children.get(row));
338             }
339
340             children.remove(row);
341         }
342
343         fireTableRowsDeleted(row, row);
344     }
345
346
347     public Object JavaDoc[] getValues(int row) {
348         int numColumns = properties.size();
349         Object JavaDoc[] values = new Object JavaDoc[numColumns];
350
351         if(indexedChildren) {
352             CommonDDBean parent = (CommonDDBean) getParent();
353
354             for(int i = 0; i < numColumns; i++) {
355                 TableEntry columnEntry = (TableEntry) properties.get(i);
356 // values[i] = parent.getAttributeValue(parentPropertyName, row, columnEntry.getPropertyName());
357
values[i] = columnEntry.getEntry(parent, row);
358             }
359         } else {
360             CommonDDBean param = (CommonDDBean) getChildren().get(row);
361
362             if(param != null) {
363                 for(int i = 0; i < numColumns; i++) {
364                     values[i] = ((TableEntry) properties.get(i)).getEntry(param);
365                 }
366             }
367         }
368
369         return values;
370     }
371
372     public boolean alreadyExists(Object JavaDoc[] values) {
373         boolean exists = false;
374
375         if(keyIndex != -1 && values != null && values[keyIndex] != null) {
376             return alreadyExistsImpl(values[keyIndex].toString());
377         }
378
379         return exists;
380     }
381
382     public boolean alreadyExists(String JavaDoc keyPropertyValue) {
383         boolean exists = false;
384
385         if(keyIndex != -1) {
386             exists = alreadyExistsImpl(keyPropertyValue);
387         }
388
389         return exists;
390     }
391
392     private boolean alreadyExistsImpl(String JavaDoc keyPropertyValue) {
393         boolean exists = false;
394
395         if(keyPropertyValue != null) {
396             TableEntry entry = (TableEntry) properties.get(keyIndex);
397             if(indexedChildren) {
398                 CommonDDBean parent = (CommonDDBean) getParent();
399 // String indexPropertyName = entry.getPropertyName();
400

401                 for(int i = 0, count = getRowCount(); i < count; i++) {
402 // if(keyPropertyValue.equals((String) parent.getAttributeValue(parentPropertyName, i, indexPropertyName))) {
403
if(keyPropertyValue.equals((String JavaDoc) entry.getEntry(parent, i))) {
404                         exists = true;
405                         break;
406                     }
407                 }
408             } else {
409                 for(int i = 0, count = getRowCount(); i < count; i++) {
410                     CommonDDBean rowBean = (CommonDDBean) getChildren().get(i);
411                     if(rowBean != null) {
412                         if(keyPropertyValue.equals(entry.getEntry(rowBean))) {
413                             exists = true;
414                             break;
415                         }
416                     }
417                 }
418             }
419         }
420
421         return exists;
422     }
423
424     /** Nested classes used to define columns and how to manipulate the data
425      * stored there.
426      */

427     public static abstract class TableEntry {
428         protected final ResourceBundle JavaDoc bundle;
429         protected final String JavaDoc resourceBase;
430         protected final String JavaDoc parentPropertyName;
431         protected final String JavaDoc propertyName;
432         protected final String JavaDoc columnName;
433         protected final boolean requiredFieldFlag;
434         protected final boolean nameFieldFlag;
435
436         public TableEntry(String JavaDoc pn, String JavaDoc c) {
437             this(pn, c, false);
438         }
439
440         public TableEntry(String JavaDoc pn, String JavaDoc c, boolean required) {
441             this(null, pn, c, required);
442         }
443
444         public TableEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required) {
445             this(ppn, pn, c, required, false);
446         }
447
448         public TableEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required, boolean isName) {
449             parentPropertyName = ppn;
450             bundle = null;
451             resourceBase = null;
452             propertyName = pn;
453             columnName = c;
454             requiredFieldFlag = required;
455             nameFieldFlag = isName;
456         }
457
458         public TableEntry(String JavaDoc ppn, String JavaDoc pn, ResourceBundle JavaDoc resBundle,
459                 String JavaDoc base, boolean required, boolean isName) {
460             parentPropertyName = ppn;
461             propertyName = pn;
462             bundle = resBundle;
463             resourceBase = base;
464             columnName = bundle.getString("LBL_" + resourceBase); // NOI18N
465
requiredFieldFlag = required;
466             nameFieldFlag = isName;
467         }
468
469         public String JavaDoc getPropertyName() {
470             return propertyName;
471         }
472
473         public String JavaDoc getColumnName() {
474             return columnName;
475         }
476
477         public boolean isRequiredField() {
478             return requiredFieldFlag;
479         }
480
481         public boolean isNameField() {
482             return nameFieldFlag;
483         }
484                 
485         public String JavaDoc getLabelName() {
486             return columnName + " :"; // NOI18N
487
}
488
489         public char getLabelMnemonic() {
490             assert bundle != null : "Coding error: incorrect column definition for " + columnName; // NOI18N
491
return bundle.getString("MNE_" + resourceBase).charAt(0); // NOI18N
492
}
493
494         public String JavaDoc getAccessibleName() {
495             assert bundle != null : "Coding error: incorrect column definition for " + columnName; // NOI18N
496
return bundle.getString("ACSN_" + resourceBase); // NOI18N
497
}
498
499         public String JavaDoc getAccessibleDescription() {
500             assert bundle != null : "Coding error: incorrect column definition for " + columnName; // NOI18N
501
return bundle.getString("ACSD_" + resourceBase); // NOI18N
502
}
503
504         public abstract Object JavaDoc getEntry(CommonDDBean parent);
505         public abstract void setEntry(CommonDDBean parent, Object JavaDoc value);
506
507         public abstract Object JavaDoc getEntry(CommonDDBean parent, int row);
508         public abstract void setEntry(CommonDDBean parent, int row, Object JavaDoc value);
509
510     }
511
512     /** Use this class for a column if the entry is stored as a value in
513      * the parent bean class.
514      */

515     public static class ValueEntry extends TableEntry {
516         public ValueEntry(String JavaDoc pn, String JavaDoc c) {
517             super(pn, c, false);
518         }
519
520         public ValueEntry(String JavaDoc pn, String JavaDoc c, boolean required) {
521             super(pn, c, required);
522         }
523
524         public ValueEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required) {
525             super(ppn, pn, c, required);
526         }
527
528         public ValueEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required, boolean isName) {
529             super(ppn, pn, c, required, isName);
530         }
531
532         public ValueEntry(String JavaDoc ppn, String JavaDoc pn, ResourceBundle JavaDoc resBundle,
533                 String JavaDoc resourceBase, boolean required, boolean isName) {
534             super(ppn, pn, resBundle, resourceBase, required, isName);
535         }
536
537         public Object JavaDoc getEntry(CommonDDBean parent) {
538             return parent.getValue(propertyName);
539         }
540
541         public void setEntry(CommonDDBean parent, Object JavaDoc value) {
542             if(value instanceof String JavaDoc && ((String JavaDoc) value).length() == 0) {
543                 value = null;
544             }
545             parent.setValue(propertyName, value);
546         }
547
548         public Object JavaDoc getEntry(CommonDDBean parent, int row) {
549             return parent.getValue(propertyName, row);
550         }
551
552         public void setEntry(CommonDDBean parent, int row, Object JavaDoc value) {
553             parent.setValue(propertyName, row, value);
554         }
555
556     }
557
558     /** Use this class for a column if the entry is stored as an attribute in
559      * the parent bean class.
560      */

561     public static class AttributeEntry extends TableEntry {
562         public AttributeEntry(String JavaDoc pn, String JavaDoc c) {
563             super(pn, c);
564         }
565
566         public AttributeEntry(String JavaDoc pn, String JavaDoc c, boolean required) {
567             super(pn, c, required);
568         }
569
570         public AttributeEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required) {
571             super(ppn, pn, c, required);
572         }
573
574         public AttributeEntry(String JavaDoc ppn, String JavaDoc pn, String JavaDoc c, boolean required, boolean isName) {
575             super(ppn, pn, c, required, isName);
576         }
577
578         public AttributeEntry(String JavaDoc ppn, String JavaDoc pn, ResourceBundle JavaDoc resBundle,
579                 String JavaDoc resourceBase, boolean required, boolean isName) {
580             super(ppn, pn, resBundle, resourceBase, required, isName);
581         }
582
583                 public Object JavaDoc getEntry(CommonDDBean parent) {
584             return parent.getAttributeValue(propertyName);
585         }
586
587         public void setEntry(CommonDDBean parent, Object JavaDoc value) {
588             String JavaDoc attrValue = null;
589             if(value != null) {
590                 attrValue = value.toString();
591             }
592             parent.setAttributeValue(propertyName, attrValue);
593         }
594
595         public Object JavaDoc getEntry(CommonDDBean parent, int row) {
596             return parent.getAttributeValue(parentPropertyName, row, propertyName);
597         }
598
599         public void setEntry(CommonDDBean parent, int row, Object JavaDoc value) {
600             String JavaDoc attrValue = null;
601             if(value != null) {
602                 attrValue = value.toString();
603             }
604
605             parent.setAttributeValue(parentPropertyName, row, propertyName, attrValue);
606             // !PW FIXME I think Cliff Draper fixed the bug this was put in for... we'll see.
607
// The issue was that attributes that were children of non-property objects and
608
// thus were attached to a boolean array, needed to have the boolean set to true
609
// in order to be recognized, otherwise, it was as if they did not exist.
610
// attributes of real properties (those that have non-attribute children as well)
611
// work fine regardless.
612
// if(Common.isBoolean(parent.beanProp(parentPropertyName).getType())) {
613
// parent.setValue(parentPropertyName, row, Boolean.TRUE);
614
// }
615
}
616     }
617
618
619     /** New interface added for migration to Sun DD API model. If the backing
620      * model stores the properties in a parent property, then this is the factory
621      * for creating instances of the parent to store each row, as added by the
622      * user.
623      */

624     public interface ParentPropertyFactory {
625
626         /* Implement this method to return a new blank instance of the correct
627          * bean type, e.g. WebserviceEndpoint, etc.
628          */

629         public CommonDDBean newParentProperty(ASDDVersion asVersion);
630
631     }
632 }
633
Popular Tags