KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > sessions > AbstractRecord


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.sessions;
23
24 import java.io.*;
25 import java.util.*;
26 import oracle.toplink.essentials.internal.helper.*;
27 import oracle.toplink.essentials.exceptions.*;
28 import oracle.toplink.essentials.sessions.Record;
29 import oracle.toplink.essentials.internal.helper.DatabaseField;
30
31 /**
32  * <p>
33  * <b>Purpose</b>: Define the abstract definition of a record for internal use.
34  * Public API should reference the Record interface.
35  * Subclasses are DatabaseRecord and XMLRecord.
36  * <p>
37  * <b>Responsibilities</b>: <ul>
38  * <li> Implement the Record and Map interfaces.
39  * </ul>
40  * @see DatabaseField
41  */

42 public abstract class AbstractRecord implements Record, Cloneable JavaDoc, Serializable, Map {
43
44     /** Use vector to store the fields/values for optimal performance.*/
45     protected Vector fields;
46
47     /** Use vector to store the fields/values for optimal performance.*/
48     protected Vector values;
49
50     /** Optimize field creation for field name lookup. */
51     protected DatabaseField lookupField;
52
53     /** INTERNAL: indicator showing that no entry exists for a given key. */
54     public static AbstractRecord.NoEntry noEntry = new AbstractRecord.NoEntry();
55
56     /**
57      * INTERNAL:
58      * NoEntry: This is used to differentiate between the two kinds
59      * of nulls: no entry exists, and the field is actually mapped
60      * to null.
61      */

62     public static class NoEntry {
63         private NoEntry() {
64         }
65     }
66
67     /**
68      * INTERNAL:
69      * TopLink converts JDBC results to collections of rows.
70      */

71     public AbstractRecord() {
72         this.fields = new Vector();
73         this.values = new Vector();
74     }
75
76     /**
77      * INTERNAL:
78      * TopLink converts JDBC results to collections of rows.
79      */

80     public AbstractRecord(int initialCapacity) {
81         this.fields = new Vector(initialCapacity);
82         this.values = new Vector(initialCapacity);
83     }
84
85     /**
86      * INTERNAL:
87      * TopLink converts JDBC results to collections of rows.
88      */

89     public AbstractRecord(Vector fields, Vector values) {
90         this.fields = fields;
91         this.values = values;
92     }
93
94     /**
95      * INTERNAL:
96      * Add the field-value pair to the row. Will not check,
97      * will simply add to the end of the row
98      */

99     public void add(DatabaseField key, Object JavaDoc value) {
100         getFields().addElement(key);
101         getValues().addElement(value);
102     }
103
104     /**
105      * PUBLIC:
106      * Clear the contents of the row.
107      */

108     public void clear() {
109         this.fields = new Vector();
110         this.values = new Vector();
111     }
112
113     /**
114      * INTERNAL:
115      * Clone the row and its values.
116      */

117     public Object JavaDoc clone() {
118         try {
119             AbstractRecord clone = (AbstractRecord)super.clone();
120             clone.setFields((Vector)getFields().clone());
121             clone.setValues((Vector)getValues().clone());
122             return clone;
123         } catch (CloneNotSupportedException JavaDoc exception) {
124         }
125
126         return null;
127     }
128
129     /**
130      * PUBLIC:
131      * Check if the value is contained in the row.
132      */

133     public boolean contains(Object JavaDoc value) {
134         return containsValue(value);
135     }
136
137     /**
138      * PUBLIC:
139      * Check if the field is contained in the row.
140      * Conform to hashtable interface.
141      */

142     public boolean containsKey(Object JavaDoc key) {
143         if (key instanceof String JavaDoc) {
144             return containsKey((String JavaDoc)key);
145         }
146         if (key instanceof DatabaseField) {
147             return containsKey((DatabaseField)key);
148         }
149
150         return false;
151     }
152
153     /**
154      * PUBLIC:
155      * Check if the field is contained in the row.
156      */

157     public boolean containsKey(String JavaDoc fieldName) {
158         // Optimized the field creation.
159
if (this.lookupField == null) {
160             this.lookupField = new DatabaseField(fieldName);
161         } else {
162             this.lookupField.resetQualifiedName(fieldName);
163         }
164         return containsKey(this.lookupField);
165     }
166
167     /**
168      * INTERNAL:
169      * Check if the field is contained in the row.
170      */

171     public boolean containsKey(DatabaseField key) {
172         // Optimize check.
173
int index = key.getIndex();
174         if ((index >= 0) && (index < getFields().size())) {
175             DatabaseField field = (DatabaseField)getFields().elementAt(index);
176             if ((field == key) || field.equals(key)) {
177                 return true;
178             }
179         }
180         return getFields().contains(key);
181     }
182
183     /**
184      * PUBLIC:
185      * Check if the value is contained in the row.
186      */

187     public boolean containsValue(Object JavaDoc value) {
188         return getValues().contains(value);
189     }
190
191     /**
192      * PUBLIC:
193      * Returns an Enumeration of the values.
194      */

195     public Enumeration elements() {
196         return getValues().elements();
197     }
198
199     /**
200      * PUBLIC:
201      * Returns a set of the keys.
202      */

203     public Set entrySet() {
204         int size = this.size();
205         Map tempMap = new HashMap(size);
206         for (int i = 0; i < size; i++) {
207             tempMap.put(this.getFields().elementAt(i), this.getValues().elementAt(i));
208         }
209         return tempMap.entrySet();
210     }
211
212     /**
213      * PUBLIC:
214      * Retrieve the value for the field name.
215      * A field is constructed on the name to check the hash table.
216      * If missing null is returned.
217      */

218     public Object JavaDoc get(Object JavaDoc key) {
219         if (key instanceof String JavaDoc) {
220             return get((String JavaDoc)key);
221         } else if (key instanceof DatabaseField) {
222             return get((DatabaseField)key);
223         }
224         return null;
225     }
226
227     /**
228      * PUBLIC:
229      * Retrieve the value for the field name.
230      * A field is constructed on the name to check the hash table.
231      * If missing null is returned.
232      */

233     public Object JavaDoc get(String JavaDoc fieldName) {
234         Object JavaDoc value = getIndicatingNoEntry(fieldName);
235         if (value == oracle.toplink.essentials.internal.sessions.AbstractRecord.noEntry) {
236             return null;
237         }
238         return value;
239     }
240
241     /**
242      * PUBLIC:
243      * Retrieve the value for the field name.
244      * A field is constructed on the name to check the hash table.
245      * If missing DatabaseRow.noEntry is returned.
246      */

247     public Object JavaDoc getIndicatingNoEntry(String JavaDoc fieldName) {
248         // Optimized the field creation.
249
if (this.lookupField == null) {
250             this.lookupField = new DatabaseField(fieldName);
251         } else {
252             this.lookupField.resetQualifiedName(fieldName);
253         }
254         return getIndicatingNoEntry(this.lookupField);
255     }
256
257     /**
258      * INTERNAL:
259      * Retrieve the value for the field. If missing null is returned.
260      */

261     public Object JavaDoc get(DatabaseField key) {
262         Object JavaDoc value = getIndicatingNoEntry(key);
263         if (value == oracle.toplink.essentials.internal.sessions.AbstractRecord.noEntry) {
264             return null;
265         }
266         return value;
267     }
268
269     //----------------------------------------------------------------------------//
270
public Object JavaDoc getValues(DatabaseField key) {
271         return get(key);
272     }
273
274     public Object JavaDoc getValues(String JavaDoc key) {
275         return get(key);
276     }
277
278     //----------------------------------------------------------------------------//
279

280     /**
281      * INTERNAL:
282      * Retrieve the value for the field. If missing DatabaseRow.noEntry is returned.
283      */

284     public Object JavaDoc getIndicatingNoEntry(DatabaseField key) {
285         // PERF: Direct variable access.
286
// Optimize check.
287
int index = key.getIndex();
288         if ((index >= 0) && (index < this.fields.size())) {
289             DatabaseField field = (DatabaseField)this.fields.elementAt(index);
290             if ((field == key) || field.equals(key)) {
291                 return this.values.elementAt(index);
292             }
293         }
294         index = this.fields.indexOf(key);
295         if (index >= 0) {
296             // PERF: If the fields index was not set, then set it.
297
if (key.getIndex() == -1) {
298                 key.setIndex(index);
299             }
300             return this.values.elementAt(index);
301         } else {
302             return oracle.toplink.essentials.internal.sessions.AbstractRecord.noEntry;
303         }
304     }
305
306     /**
307      * INTERNAL:
308      * Returns the row's field with the same name.
309      */

310     public DatabaseField getField(DatabaseField key) {
311         // Optimize check.
312
int index = key.getIndex();
313         if ((index >= 0) && (index < getFields().size())) {
314             DatabaseField field = (DatabaseField)getFields().elementAt(index);
315             if ((field == key) || field.equals(key)) {
316                 return field;
317             }
318         }
319         for (index = 0; index < getFields().size(); index++) {
320             DatabaseField field = (DatabaseField)getFields().elementAt(index);
321             if ((field == key) || field.equals(key)) {
322                 return field;
323             }
324         }
325         return null;
326     }
327
328     /**
329      * INTERNAL:
330      */

331     public Vector getFields() {
332         return fields;
333     }
334
335     /**
336      * INTERNAL:
337      */

338     public Vector getValues() {
339         return values;
340     }
341
342     /**
343      * PUBLIC:
344      * Return if the row is empty.
345      */

346     public boolean isEmpty() {
347         return size() == 0;
348     }
349
350     /**
351      * PUBLIC:
352      * Returns an Enumeration of the DatabaseField objects.
353      */

354     public Enumeration keys() {
355         return getFields().elements();
356     }
357
358     /**
359      * PUBLIC:
360      * Returns a set of the keys.
361      */

362     public Set keySet() {
363         return new HashSet(getFields());
364     }
365
366     /**
367      * INTERNAL:
368      * Merge the provided row into this row. Existing field values in this row will
369      * be replaced with values from the provided row. Fields not in this row will be
370      * added from provided row. Values not in provided row will remain in this row.
371      */

372     
373     public void mergeFrom(AbstractRecord row){
374         for (int index = 0; index < row.size(); ++index){
375             this.put(row.getFields().get(index), row.getValues().get(index));
376         }
377     }
378     
379     /**
380      * PUBLIC:
381      * Add the field-value pair to the row.
382      */

383     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) throws ValidationException {
384         if (key instanceof String JavaDoc) {
385             return put((String JavaDoc)key, value);
386         } else if (key instanceof DatabaseField) {
387             return put((DatabaseField)key, value);
388         } else {
389             throw ValidationException.onlyFieldsAreValidKeysForDatabaseRows();
390         }
391     }
392
393     /**
394      * PUBLIC:
395      * Add the field-value pair to the row.
396      */

397     public Object JavaDoc put(String JavaDoc key, Object JavaDoc value) {
398         return put(new DatabaseField(key), value);
399     }
400
401     /**
402      * INTERNAL:
403      * Add the field-value pair to the row.
404      */

405     public Object JavaDoc put(DatabaseField key, Object JavaDoc value) {
406         int index = getFields().indexOf(key);
407         if (index >= 0) {
408             Object JavaDoc oldValue = getValues().elementAt(index);
409             replaceAt(value, index);
410             return oldValue;
411         } else {
412             add(key, value);
413         }
414
415         return null;
416     }
417
418     /**
419      * PUBLIC:
420      * Add all of the elements.
421      */

422     public void putAll(Map map) {
423         Iterator entriesIterator = map.entrySet().iterator();
424         while (entriesIterator.hasNext()) {
425             Map.Entry entry = (Map.Entry)entriesIterator.next();
426             put(entry.getKey(), entry.getValue());
427         }
428     }
429
430     /**
431      * INTERNAL:
432      * Remove the field key from the row.
433      */

434     public Object JavaDoc remove(Object JavaDoc key) {
435         if (key instanceof String JavaDoc) {
436             return remove((String JavaDoc)key);
437         } else if (key instanceof DatabaseField) {
438             return remove((DatabaseField)key);
439         }
440         return null;
441     }
442
443     /**
444      * INTERNAL:
445      * Remove the field key from the row.
446      */

447     public Object JavaDoc remove(String JavaDoc fieldName) {
448         return remove(new DatabaseField(fieldName));
449     }
450
451     /**
452      * INTERNAL:
453      * Remove the field key from the row.
454      */

455     public Object JavaDoc remove(DatabaseField key) {
456         int index = getFields().indexOf(key);
457         if (index >= 0) {
458             getFields().removeElementAt(index);
459             Object JavaDoc value = getValues().elementAt(index);
460             getValues().removeElementAt(index);
461             return value;
462         }
463         return null;
464     }
465
466     /**
467      * INTERNAL:
468      * replaces the value at index with value
469      */

470     public void replaceAt(Object JavaDoc value, int index) {
471         getValues().setElementAt(value, index);
472     }
473
474     protected void setFields(Vector fields) {
475         this.fields = fields;
476     }
477
478     protected void setValues(Vector values) {
479         this.values = values;
480     }
481
482     /**
483      * PUBLIC:
484      * Return the number of field/value pairs in the row.
485      */

486     public int size() {
487         return getFields().size();
488     }
489
490     /**
491      * INTERNAL:
492      */

493     public String JavaDoc toString() {
494         StringWriter writer = new StringWriter();
495         writer.write(Helper.getShortClassName(getClass()));
496         writer.write("(");
497
498         for (int index = 0; index < getFields().size(); index++) {
499             writer.write(Helper.cr());
500             writer.write("\t");
501             writer.write(String.valueOf((getFields().elementAt(index))));
502             writer.write(" => ");
503             writer.write(String.valueOf((getValues().elementAt(index))));
504         }
505         writer.write(")");
506
507         return writer.toString();
508     }
509
510     /**
511      * PUBLIC:
512      * Returns an collection of the values.
513      */

514     public Collection values() {
515         return getValues();
516     }
517 }
518
Popular Tags