KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > dataobjects > SynchronizedDataObject


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65
66 package com.jcorporate.expresso.core.dataobjects;
67
68
69 import com.jcorporate.expresso.core.db.DBException;
70 import org.apache.oro.text.regex.Pattern;
71
72 import java.util.ArrayList JavaDoc;
73 import java.util.Iterator JavaDoc;
74 import java.util.Map JavaDoc;
75
76 /**
77  * This class provides a threadsafe access to a dataobject. To be able to more
78  * safely share your dataobjects acrossed multiple threads, simple call.
79  * <p>Typical Usage:<code><pre>
80  * DataObject myobj = SynchronizedDataObject.newInstance(new MimeTypes(SecuredDBObject.SYSTEM_ACCOUNT));
81  * <p/>
82  * //We now have a wrapped MimeTypes data object
83  * myobj.setField("MimeNumber",new Integer(1));
84  * <p/>
85  * //Retrieves a set of cloned records.
86  * ArrayList records = myobj.searchAndRetrieveList();
87  * </pre></code></p>
88  *
89  * @author Michael Rimov
90  */

91
92 public class SynchronizedDataObject implements DataObject {
93     DataObject target;
94
95     SynchronizedDataObject(DataObject _target) {
96         target = _target;
97     }
98
99     /**
100      * Call this to wrap your data object in a threadsafe wrapper.
101      *
102      * @param wrappedObject the object to wrap.
103      * @return a DataObject who's implementation is threadsafe.
104      */

105     public static synchronized DataObject newInstance(DataObject wrappedObject) {
106         return new SynchronizedDataObject(wrappedObject);
107     }
108
109     /**
110      * Returns the object embedded within the field keyed by the fieldName
111      * parameter
112      *
113      * @param fieldName The name of the field to get
114      * @return The object if it isn't null for the data value or null.
115      * @throws DBException upon error
116      */

117     public synchronized DataField getDataField(String JavaDoc fieldName) throws DBException {
118         return target.getDataField(fieldName);
119     }
120
121
122     /**
123      * Returna a list of all field names available to this class in order.
124      *
125      * @return java.util.Iterator
126      */

127     public synchronized Iterator JavaDoc getFieldListIterator() {
128         return (new ArrayList JavaDoc(target.getMetaData().getFieldListArray())).iterator();
129     }
130
131     /**
132      * Retrieve iterator of all keys
133      *
134      * @return java.util.Itaerator Each iteration will return the name of
135      * the next key in the list.
136      * @throws DBException upon error
137      * @todo Change DBException to DataException as soon as possible
138      */

139     public synchronized Iterator JavaDoc getKeyFieldListIterator() throws DBException {
140         return (new ArrayList JavaDoc(target.getMetaData().getKeyFieldListArray())).iterator();
141     }
142
143
144     /**
145      * Retrieve the database object's metadata. Metadata is a description of the
146      * database object, so it contains static information such as as description,
147      * field names, field types. Etc.
148      * <p>For implementers of this interface: It is best to store the metadata
149      * somewhere rather than recreating it each and every time. For low-memory
150      * requirements, a WeakHashMap is recommended</p>
151      *
152      * @return a built DataObjectMetaData for this database object
153      */

154     public synchronized DataObjectMetaData getMetaData() {
155         return target.getMetaData();
156     }
157
158     /**
159      * Retrieves the metadata for a particular field name
160      *
161      * @param fieldName The name of the field to retrieve the metadata for.
162      * @return <?ode>DataFieldMetaData</code> the metadata associated with this
163      * field.
164      * @throws IllegalArgumentException if the fieldName does not exist.
165      */

166     public synchronized DataFieldMetaData getFieldMetaData(String JavaDoc fieldName) {
167         return target.getFieldMetaData(fieldName);
168     }
169
170     /**
171      * Directly sets the field value without getting the datafield object
172      *
173      * @param fieldName the name of the field to set
174      * @param o the object value to set it to.
175      */

176     public synchronized void set(String JavaDoc fieldName, Object JavaDoc o) throws DataException {
177         target.set(fieldName, o);
178     }
179
180     /**
181      * Checks to see if two data objects are equal. This is extremely important
182      * in conflict resolution.
183      *
184      * @param otherObject the other object to compare to.
185      * @return true if the two objects are considered equal
186      */

187     public synchronized boolean equals(Object JavaDoc otherObject) {
188         return target.equals(otherObject);
189     }
190
191     /**
192      * Adds the record to the defined data source.
193      */

194     public synchronized void add() throws DBException {
195         target.add();
196     }
197
198
199     /**
200      * Updates the record to the defined datasource
201      */

202     public synchronized void update() throws DBException {
203         target.update();
204     }
205
206     /**
207      * Deletes this defined record.
208      */

209     public synchronized void delete() throws DBException {
210         target.delete();
211     }
212
213
214     /**
215      * Clears all currently loaded fields
216      */

217     public synchronized void clear() throws DBException {
218         target.clear();
219     }
220
221
222     /**
223      * Sets the data context that this object is residing in. This is identical
224      * to the pre-Expresso 5.0 <code>setDBName()</code>
225      *
226      * @param newContext the new name of the data context.
227      * @throws IllegalArgumentException if the DataContext does not exist
228      */

229     public synchronized void setDataContext(String JavaDoc newContext) {
230         target.setDataContext(newContext);
231     }
232
233     /**
234      * Returns the name of the currently set DataContext
235      *
236      * @return java.lang.String
237      */

238     public synchronized String JavaDoc getDataContext() {
239         return target.getDataContext();
240     }
241
242     /**
243      * {@inheritDoc}
244      *
245      * @throws DataException upon setField error.
246      */

247     public synchronized void setFieldsWithDefaults() throws DataException {
248         target.setFieldsWithDefaults();
249     }
250
251     /**
252      * Returns the name of the physical database that we're talking with. This
253      * is opposed to getDataContext() which returns the security context as well.
254      * getMappedDataContext() is strictly used to get at the low level database
255      * connection.
256      *
257      * @return java.lang.String... the context we've mapped to.
258      */

259     public synchronized String JavaDoc getMappedDataContext() {
260         return target.getMappedDataContext();
261     }
262
263
264     /**
265      * Set an attribute. Attributes are temporary (e.g. not stored in the DBMS) values
266      * associated with this particular DB object instance.
267      *
268      * @param attributeName The name of the attribute being defined
269      * @param attributeValue The object to store under this attribute name
270      */

271     public synchronized void setAttribute(String JavaDoc attributeName, Object JavaDoc attributeValue) {
272         target.setAttribute(attributeName, attributeValue);
273     }
274
275     /**
276      * Return an "attribute". Attributes are temporary (e.g. not stored in the DBMS)
277      * values associated with this particular DB object instance.
278      *
279      * @param attributeName The attribute name to check
280      * @return the object associated with this attribute
281      */

282     public synchronized Object JavaDoc getAttribute(String JavaDoc attributeName) {
283         return target.getAttribute(attributeName);
284     }
285
286     /**
287      * Returns a <b>Read Only</b> Map containing all the current attributes set
288      * for this particular data object instance.
289      *
290      * @return Read Only <code>java.util.Map</code>
291      */

292     public synchronized Map JavaDoc getAllAttributes() {
293         return java.util.Collections.unmodifiableMap(target.getAllAttributes());
294     }
295
296
297     /**
298      * Use this function to acquire the Executor interface that is associated
299      * with this data object
300      *
301      * @return DataExecutorInterface or null if no Executor has been associated
302      * with this object
303      */

304     public synchronized DataExecutorInterface getExecutor() {
305         return target.getExecutor();
306     }
307
308     /**
309      * Use this function to acquire the DataQueryInterface that is associated
310      * with this data object
311      *
312      * @return DataQueryInterface or null if no QueryInterface has been
313      * associated with this object
314      */

315     public synchronized DataQueryInterface getQueryInterface() {
316         return target.getQueryInterface();
317     }
318
319     /**
320      * Check that a given value is valid for a given field.
321      * This method is overriden by specific DBObjects to do their own field-level
322      * validations - they should also call super in order to do the
323      * standard stuff. Every field is automatically checked by this method before the
324      * database is updated.
325      *
326      * @param fieldName Name of the field to verify
327      * @param fieldValue Value of the field to be evaluated
328      * @throws DBException If the value is not valid
329      */

330     public synchronized void checkField(String JavaDoc fieldName, String JavaDoc fieldValue) throws DBException {
331         target.checkField(fieldName, fieldValue);
332     }
333
334
335     /**
336      * Retrieve the status code of the dataobject.
337      *
338      * @return java.lang.String
339      */

340     public synchronized String JavaDoc getStatus() {
341         return target.getStatus();
342     }
343
344
345     /**
346      * Retrieve a list of valid value object for this particular dbobject
347      *
348      * @param fieldName name of the field to retrieve the list for.
349      * @return java.util.List of valid values
350      * @throws DBException upon error
351      */

352     public synchronized java.util.List JavaDoc getValidValuesList(String JavaDoc fieldName) throws DBException {
353         return java.util.Collections.unmodifiableList(target.getValidValuesList(fieldName));
354     }
355
356
357     /**
358      * Sets the DataObject's locale
359      *
360      * @param newLocale the New locale object
361      */

362     public synchronized void setLocale(java.util.Locale JavaDoc newLocale) {
363         target.setLocale(newLocale);
364     }
365
366     /**
367      * Retrieve the DBObject's current locale
368      *
369      * @return java.util.Locale
370      */

371     public synchronized java.util.Locale JavaDoc getLocale() {
372         return target.getLocale();
373     }
374
375
376     /**
377      * Specify a maximum number of records to be retrieved in any subsequent
378      * searchAndRetrieve() call. Records will be retrieved (in the specified
379      * sort order) until the specified maximum is reached, then the remainder
380      * of the result set is discarded. Specifying zero indicates that all
381      * records are to be retrieved.
382      *
383      * @param newMax The maximum number of records to retrieve.
384      * @throws DBException If the max number is less than 0
385      */

386     public synchronized void setMaxRecords(int newMax) throws DBException {
387         target.setMaxRecords(newMax);
388     }
389
390
391     /**
392      * A DB Object can be told to only retrieve a certain number of records. If a
393      * "max records" value has been specified, this method provides access to it.
394      *
395      * @return The maximum number of records that should be retrieved, or zero
396      * if no max has been set
397      */

398     public synchronized int getMaxRecords() {
399         return target.getMaxRecords();
400     }
401
402
403     /**
404      * Specifies the number of records that should be skipped over
405      * before any data from the <code>ResultSet</code>
406      * is retrieved in any subsequent
407      * searchAndRetrieve() call. Records will be skipped over (in the specified
408      * sort order) until the record counts is equal to or greater
409      * than the offset record. Specifying zero indicates that no
410      * records should be skipped over and the
411      * <code>ResultSet</code> immediately from the start.
412      *
413      * @param newOffset The maximum number of records to retrieve.
414      * @throws DBException If the max number is less than 0
415      * <p/>
416      * author Peter Pilgrim <peterp at xenonsoft dot demon dot co dot uk>
417      */

418     public synchronized void setOffsetRecord(int newOffset) throws DBException {
419         target.setOffsetRecord(newOffset);
420     }
421
422
423     /**
424      * Gets the number of records that be skipped. The offset records.
425      * A DB Object can be told to skip a certain number of
426      * records, before reading records from the <code>ResultSet</code>.
427      * <p/>
428      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
429      *
430      * @return The maximum number of records that should be
431      * skipped over before reading the data records.
432      * @see #setOffsetRecord(int)
433      */

434     public synchronized int getOffsetRecord() {
435         return target.getOffsetRecord();
436     }
437
438     /**
439      * Performs a datasource search so that the criteria set in the DataObject
440      * is used.
441      * <p>Note: This particular implementation, to be threadsafe, returns a new
442      * array instance, so it is particularly slow and memory intensive. However, for
443      * the scope of the class, it is at least threadsafe.</p>
444      *
445      * @param sortOrder A pipe delimited string specifying the field(s) to be sorted upon.
446      * May be a single field without any pipes.
447      * @return <code>java.util.List</code> of objects. May be an empty list if no
448      * objects were found.
449      * @throws DBException upon error performing the search
450      */

451     public ArrayList JavaDoc searchAndRetrieveList(String JavaDoc sortOrder) throws DBException {
452         return new ArrayList JavaDoc(target.searchAndRetrieveList(sortOrder));
453     }
454
455     /**
456      * Performs a datasource search so that the criteria set in the DataObject
457      * is used. There is no specified sort order for this version of the method
458      * <p>Note: This particular implementation, to be threadsafe, returns a new
459      * array instance, so it is particularly slow and memory intensive. However, for
460      * the scope of the class, it is at least threadsafe.</p>
461      *
462      * @return <code>java.util.List</code> of objects. May be an empty list if no
463      * objects were found.
464      * @throws DBException upon error performing the search
465      */

466     public ArrayList JavaDoc searchAndRetrieveList() throws DBException {
467         return new ArrayList JavaDoc(target.searchAndRetrieveList());
468     }
469
470
471     /**
472      * Finds a single record based upon the criteria specified by the <code>DataTransferObject</code>
473      *
474      * @return boolean true if a record was found, and the <i>criteria</i> parameter
475      * is filled with the first data object found.
476      * @throws DBException upon error performing the search
477      */

478     public synchronized boolean find() throws DBException {
479         return target.find();
480     }
481
482     /**
483      * Just like find, but only retrieves the count, not the records themselves.
484      *
485      * @return integer Count of the records matching the criteria
486      * @throws DBException If the search could not be completed
487      */

488     public synchronized int count() throws DBException {
489         return target.count();
490     }
491
492     /**
493      * Every class that can stay in the system cache must define a way to get
494      * a <b>unique</b> key
495      *
496      * @return The cache key for this item.
497      */

498     public String JavaDoc getKey() {
499         return target.getKey();
500     }
501
502
503     /**
504      * Sets the status of the object.
505      *
506      * @param statusValue
507      */

508     public synchronized void setStatus(String JavaDoc statusValue) {
509         target.setStatus(statusValue);
510     }
511
512     /**
513      * Retrieve the native object type for the given field name.
514      *
515      * @param fieldName the name of the field to retrieve
516      * @return Object or null if the field was null
517      * @throws DataException upon error
518      * @throws IllegalArgumentException if fieldname is invalid
519      */

520     public synchronized Object JavaDoc get(String JavaDoc fieldName) throws DataException {
521         return target.get(fieldName);
522     }
523
524
525     /**
526      * Retrieve the field value as a String
527      *
528      * @param fieldName the name of the field to retrieve
529      * @return Object or null if the field was null
530      * @throws DBException upon error
531      * @throws IllegalArgumentException if fieldname is invalid
532      */

533     public synchronized String JavaDoc getField(String JavaDoc fieldName) throws DBException {
534         return target.getField(fieldName);
535     }
536
537     /**
538      * Set a regular expression "mask" for this base data object that specifies it's
539      * valid values. The mask should already be compiled by the regular
540      * expression compiler
541      *
542      * @param newMask The compiled regular expression mask
543      */

544     public void setGlobalMask(Pattern newMask) {
545         target.setGlobalMask(newMask);
546     }
547
548     /**
549      * Get the compiled regular expression for this base data object.
550      *
551      * @return the precompiled regular expression mask
552      */

553     public Pattern getGlobalMask() {
554         return target.getGlobalMask();
555     }
556
557
558     /**
559      * Return boolean if the data object has a mask set
560      *
561      * @return True if the data object mask is set, else false if it is not
562      */

563     public boolean isGlobalMasked() {
564         return target.isGlobalMasked();
565     } /* isMasked() */
566
567     /**
568      * Returns a hash code value for the object.
569      *
570      * @return a hash code value for this object.
571      * @todo Implement this java.lang.Object method
572      */

573     public int hashCode() {
574         return target.hashCode();
575     }
576
577 }
578
Popular Tags