View Javadoc
1   /*
2    * $Source$
3    * $Revision$
4    *
5    * Copyright (C) 2000 William Chesters
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     William Chesters <williamc At paneris.org>
42   *     http://paneris.org/~williamc
43   *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44   */
45  
46  package org.melati.poem;
47  
48  import java.io.PrintStream;
49  import java.util.Enumeration;
50  import java.util.Map;
51  
52  /**
53   * The object representing a single table row; this is the <B>PO</B> in POEM!
54   * <p>
55   * Instances are also used to represent selection criteria.
56   *
57   * @author timp
58   * @since 4 Jul 2007
59   *
60   */
61  public interface Persistent extends Persistable, Treeable {
62  
63    /**
64     * @return whether this object has been persisted
65     */
66    boolean statusNonexistent();
67  
68    /**
69     * @return whether this object has been deleted
70     */
71    boolean statusExistent();
72  
73    /** 
74     * A convenience method to create this Persistent.
75     */
76    void makePersistent();
77  
78    /**
79     * The Table from which the object comes, 
80     * complete with metadata.
81     * @return the Table
82     */
83    Table<?> getTable();
84    
85    /**
86     * @param table
87     */
88    //void setTable(Table table, Integer Troid);
89  
90    /**
91     * @return The database from which the object comes.  <I>I.e.</I>
92     * <TT>getTable().getDatabase()</TT>.
93     */
94    Database getDatabase();
95  
96    /**
97     * Lock without actually reading.
98     */
99    void existenceLock();
100 
101   /**
102    * Check that you have read access to the object.  Which is to say: the
103    * <TT>AccessToken</TT> associated with the POEM task executing in the
104    * running thread confers the <TT>Capability</TT> required for inspecting the
105    * object's fields.  The access token is set when the task is invoked using
106    * <TT>Database.inSession</TT>.  The capability is determined by
107    * <TT>getCanRead</TT>, which by default means the capability defined in the
108    * record's <TT>canread</TT> field in the database.  If that's <TT>null</TT>,
109    * the table's default <TT>canread</TT> capability is obtained using
110    * <TT>getTable().getDefaultCanRead()</TT>.  If that is <TT>null</TT> as
111    * well, access is granted unconditionally.
112    *
113    * <P>
114    *
115    * Although this check can in theory be quite time-consuming, in practice
116    * this isn't a problem, because the most recent access token for which the
117    * check succeeded is cached; repeat accesses from within the same 
118    * transaction are therefore quick.
119    *
120    * <P>
121    *
122    * Application programmers can override this method to implement their own
123    * programmatic access policies.  For instance, POEM's own <TT>TableInfo</TT>
124    * class overrides it with an empty method in order to disable all read
125    * protection on <TT>TableInfo</TT> objects.  More interestingly, you could
126    * implement a check that depends on the values of the object's fields:
127    * for example, you could allow read access to an invoice record to its
128    * issuing and receiving parties.
129    *
130    * @param token       the access token on the basis of which readability is
131    *                    being claimed
132    *
133    * @exception AccessPoemException if the check fails
134    *
135    * @see Database#inSession
136    * @see JdbcTable#getDefaultCanRead
137    *
138    */
139 
140   void assertCanRead(AccessToken token) throws AccessPoemException;
141 
142   /**
143    * @throws AccessPoemException if current accessToken does not grant read capability
144    */
145   void assertCanRead() throws AccessPoemException;
146 
147   /**
148    * @return Whether the object is readable by current AccessToken
149    *
150    * @see #assertCanRead()
151    */
152 
153   boolean getReadable();
154 
155   /**
156    * Check that you have write access to the object.  Which is to say: the
157    * <TT>AccessToken</TT> associated with the POEM task executing in the
158    * running thread confers the <TT>Capability</TT> required for updating the
159    * object's fields.  The remarks made about <TT>assertCanRead</TT> apply
160    * (<I>mutatis mutandis</I>) here as well.
161    *
162    * @see #assertCanRead()
163    * @see JdbcTable#getDefaultCanWrite
164    */
165 
166   void assertCanWrite(AccessToken token) throws AccessPoemException;
167 
168   /**
169    * @throws AccessPoemException if current accessToken does not grant wraite capability
170    */
171   void assertCanWrite() throws AccessPoemException;
172 
173   /**
174    * Check that you have delete access to the object.  Which is to say: the
175    * <TT>AccessToken</TT> associated with the POEM task executing in the
176    * running thread confers the <TT>Capability</TT> required for updating the
177    * object's fields.  The remarks made about <TT>assertCanRead</TT> apply
178    * (<I>mutatis mutandis</I>) here as well.
179    *
180    * @see #assertCanRead()
181    * @see JdbcTable#getDefaultCanDelete
182    *
183    */
184 
185   void assertCanDelete(AccessToken token) throws AccessPoemException;
186 
187   /**
188    * @throws AccessPoemException if current accessToken does not grant delete capability
189    */
190   void assertCanDelete() throws AccessPoemException;
191 
192   /**
193    * Check that you have create access to the object.  Which is to say: the
194    * <TT>AccessToken</TT> associated with the POEM task executing in the
195    * running thread confers the <TT>Capability</TT> required for creating the
196    * object. The capability is determined solely by <TT>getCanCreate</TT>
197    * from the table. Unlike <TT>assertCanRead</TT> and <TT>assertCanWrite</TT>
198    * there is no idea of having a default <TT>Capability</TT> defined 
199    * in the table which could be overridden by a <TT>canwrite</TT> field
200    * in the persistent (since the persistent has not yet been been written).
201    *
202    * <P>
203    *
204    * Application programmers can override this method to implement their own
205    * programmatic access policies.
206    *
207    * @see #assertCanRead()
208    * @see #assertCanWrite()
209    * @see JdbcTable#getCanCreate
210    */
211 
212   void assertCanCreate(AccessToken token);
213 
214   /**
215    * @throws AccessPoemException if current accessToken does not grant create capability
216    */
217   void assertCanCreate() throws AccessPoemException;
218 
219   /**
220    * The `identifying value' of one of the object's fields.  This is the value
221    * which is actually stored in the database, given to you as a basic Java
222    * type; currently, the only fields for which this differs from the `true
223    * value' returned from <TT>getCooked</TT> are reference fields with type
224    * <TT>ReferencePoemType</TT> and <TT>StringKeyReferencePoemType</TT>.
225    *
226    * <P>
227    *
228    * If the field <TT><I>baz</I></TT> is defined in the DSD as part of a table
229    * called <TT><I>foo</I></TT>, then the table's records will be represented
230    * by an application-specialised subclass of <TT>Persistent</TT> called
231    * <TT><I>Foo</I></TT> which provides a typed <TT>get<I>Baz</I></TT> method.
232    * So the easiest way to be sure of your types is to predeclare any fields
233    * you use in the DSD, use the typed field-access methods, and let the
234    * compiler take the strain.  When working with generic <TT>Persistent</TT>s,
235    * you probably want to use <TT>getField</TT>.
236    *
237    * <P>
238    *
239    * The value returned is relative to the transaction associated with the
240    * calling thread, as set up by <TT>Database.inSession</TT>.  This means that
241    * you never see the value of a field change in your transaction because of
242    * another transaction's activities, unless you do a
243    * <TT>PoemThread.commit()</TT> or a <TT>PoemThread.rollback()</TT>.  If you
244    * need to, you can store a <TT>Persistent</TT> in a permanent data structure
245    * and access it in different sessions over time---or even from concurrently
246    * running sessions, though this may slow down access checking; each
247    * transaction will see the value it expects.
248    *
249    * @param name        the name of the field (<I>i.e.</I> the name of the
250    *                    column in the RDBMS and DSD)
251    *
252    * @return The field's `identifying value'; this will be a <TT>String</TT>,
253    *         <TT>Boolean</TT>, <TT>Integer</TT>, <TT>Double</TT> or
254    *         <TT>Date</TT> as appropriate.  If the field is a reference field,
255    *         the result is an <TT>Integer</TT> giving the troid of the referee.
256    *         If you want references to be resolved transparently to
257    *         <TT>Persistent</TT>s, use <TT>getCooked</TT>.  
258    *         If you want a string representation of the field, 
259    *         use <TT>getRawString</TT> or <TT>getCookedString</TT>.
260    *
261    * @exception NoSuchColumnPoemException
262    *                if the field named doesn't exist
263    * @exception AccessPoemException
264    *                if the calling thread doesn't have read access to the
265    *                object (see <TT>assertCanRead</TT>)
266    *
267    * @see #getCooked
268    * @see #getRawString
269    * @see #getCookedString
270    * @see #getField
271    * @see Database#inSession
272    * @see PoemThread#commit
273    * @see PoemThread#rollback
274    * @see #assertCanRead()
275    */
276   Object getRaw(String name) throws NoSuchColumnPoemException,
277           AccessPoemException;
278 
279   /**
280    * A string representation of the `identifying value' of one of the object's
281    * fields.  The value returned is relative to the transaction associated with
282    * the calling thread, as set up by <TT>Database.inSession</TT>: see the
283    * remarks made about <TT>getRaw</TT>.
284    *
285    * @param name        the name of the field (<I>i.e.</I> the name of the
286    *                    column in the RDBMS and DSD)
287    *
288    * @return Roughly, the string the underlying RDBMS would display if asked
289    *         to show the field's value.  If you want reference fields to be
290    *         represented by their referee's <TT>displayString()</TT> (by
291    *         default, its primary display field) rather than by its troid, use
292    *         <TT>getCookedString</TT>.  If you want the field's value as an
293    *         appropriate Java type like <TT>Integer</TT>, use <TT>getRaw</TT>
294    *         or <TT>getCooked</TT>---or an equivalent, but type-safe, method
295    *         derived from the DSD.
296    *
297    * @exception NoSuchColumnPoemException
298    *                if the field named doesn't exist
299    * @exception AccessPoemException
300    *                if the calling thread doesn't have read access to the
301    *                object (see <TT>assertCanRead</TT>)
302    *
303    * @see #getCookedString
304    * @see #getRaw
305    * @see #getCooked
306    * @see #assertCanRead()
307    */
308 
309   String getRawString(String name) throws AccessPoemException,
310           NoSuchColumnPoemException;
311 
312   /**
313    * Set the `identifying value' of one of the record's fields.  This is the
314    * value which is actually stored in the database, given by you as a basic
315    * Java type; currently, the only fields for which this differs from the
316    * `true value' expected by <TT>setCooked</TT> are reference fields with type
317    * <TT>ReferencePoemType</TT>.
318    *
319    * <P>
320    *
321    * If the field <TT><I>baz</I></TT> is defined in the DSD as part of a table
322    * called <TT><I>foo</I></TT>, then the table's records will be represented
323    * by an application-specialised subclass of <TT>Persistent</TT> called
324    * <TT><I>Foo</I></TT> which provides a typed <TT>set<I>Baz</I></TT>
325    * method.  So the easiest way to be sure of your types is to predeclare any
326    * fields you use in the DSD, use the typed field-access methods, and let the
327    * compiler take the strain.  When working with generic <TT>Persistent</TT>s,
328    * you probably mean <TT>setRawString</TT> anyway.
329    *
330    * <P>
331    *
332    * The change you make to the field's value will only be visible to the
333    * calling thread, until it successfully completes the task started by
334    * <TT>Database.inSession</TT>, or does an explicit
335    * <TT>PoemThread.commit()</TT>.  Up to that point the change can be undone
336    * by calling <TT>PoemThread.rollback()</TT>, and will be undone
337    * automatically if the task terminates with an uncaught exception.
338    *
339    * <P>
340    *
341    * In fact, your changes are not written down to the database, even relative
342    * to an uncommitted transaction, until it's actually necessary.  So multiple
343    * calls to <TT>setRaw</TT> and relatives will not cause multiple SQL
344    * <TT>UPDATE</TT>s to be issued.
345    *
346    * @param name        the name of the field (<I>i.e.</I> the name of the
347    *                    column in the RDBMS and DSD)
348    *
349    * @param raw       The new value for the field: a <TT>String</TT>,
350    *                    <TT>Boolean</TT>, <TT>Integer</TT>, <TT>Double</TT> or
351    *                    <TT>Date</TT> as appropriate.  If the field is a
352    *                    reference field: an <TT>Integer</TT> giving the troid
353    *                    of the referee.  If you want to pass referees as actual
354    *                    <TT>Persistent</TT>s, use <TT>setCooked</TT>.  If you
355    *                    want to set the field from a string representation
356    *                    (<I>e.g.</I> typed in by the user), use
357    *                    <TT>setRawString</TT>.
358    *
359    * @exception NoSuchColumnPoemException
360    *                if the field named doesn't exist
361    * @exception AccessPoemException
362    *                if the calling thread doesn't have write access to the
363    *                object (see <TT>assertCanWrite</TT>)
364    * @exception ValidationPoemException
365    *                if <TT>raw</TT> is not a valid value for the field
366    *                (<I>e.g.</I> a string is too long)
367    *
368    * @see #setCooked
369    * @see #setRawString
370    * @see #assertCanWrite()
371    * @see Database#inSession
372    * @see PoemThread#commit
373    * @see PoemThread#rollback
374    */
375 
376   void setRaw(String name, Object raw) throws NoSuchColumnPoemException,
377           AccessPoemException, ValidationPoemException;
378 
379   /**
380    * Set the `identifying value' of one of the record's fields from a string
381    * representation.  The remarks about sessions (transactions) and DSD-derived
382    * type-safe methods made for <TT>setRaw</TT> apply here too.
383    *
384    * @param name        the name of the field (<I>i.e.</I> the name of the
385    *                    column in the RDBMS and DSD)
386    *
387    * @param string      A string that will be parsed to obtain the new value
388    *                    for the field.  If it's a reference field, this should
389    *                    be a decimal representation of the referee's troid.  If
390    *                    you want to set fields to values defined by appropriate
391    *                    Java types, use <TT>setRaw</TT> or <TT>setCooked</TT>.
392    *
393    * @exception NoSuchColumnPoemException
394    *                if the field named doesn't exist
395    * @exception AccessPoemException
396    *                if the calling thread doesn't have write access to the
397    *                object (see <TT>assertCanWrite</TT>)
398    * @exception ParsingPoemException
399    *                if <TT>string</TT> doesn't parse as a value of the
400    *                appropriate type
401    * @exception ValidationPoemException
402    *                if <TT>string</TT> parses to an invalid value for the field
403    *                (<I>e.g.</I> it's too wide)
404    *
405    * @see #setRaw
406    * @see #setCooked
407    * @see #assertCanWrite()
408    */
409 
410   void setRawString(String name, String string)
411           throws NoSuchColumnPoemException, AccessPoemException,
412           ParsingPoemException, ValidationPoemException;
413 
414   /**
415    * The `true value' of one of the object's fields.  This is the
416    * fully-interpreted value rather than the one actually stored in the
417    * database; currently, the only fields for which this differs from the
418    * `identifying value' return from <TT>getRaw</TT> are reference fields
419    * with type <TT>ReferencePoemType</TT>.
420    *
421    * <P>
422    *
423    * The value returned is relative to the transaction associated with the
424    * calling thread, as set up by <TT>Database.inSession</TT>: see the remarks
425    * made about <TT>getRaw</TT>.
426    *
427    * <P>
428    *
429    * The easiest way to be sure of your types is to predeclare any fields you
430    * use in the DSD, or use <TT>getField</TT>.  Again, see the remarks made
431    * about <TT>getRaw</TT>.
432    *
433    * @return The field's `true value'; this will be a <TT>String</TT>,
434    *         <TT>Boolean</TT>, <TT>Integer</TT>, <TT>Double</TT>,
435    *         <TT>Date</TT>, or, if the field is a reference field, a
436    *         <TT>Persistent</TT> representing the referee.  If you just want to
437    *         see referees' troids, use <TT>getRaw</TT>.  If you want a string
438    *         representation of the field, use <TT>getRawString</TT> or
439    *         <TT>getCookedString</TT>.
440    *
441    * @exception NoSuchColumnPoemException
442    *                if the field named doesn't exist
443    * @exception AccessPoemException
444    *                if the calling thread doesn't have read access to the
445    *                object (see <TT>assertCanRead</TT>)
446    *
447    * @see #getRaw
448    * @see #getRawString
449    * @see #getCookedString
450    * @see #getField
451    * @see #assertCanRead()
452    */
453 
454   Object getCooked(String name) throws NoSuchColumnPoemException,
455           AccessPoemException;
456 
457   /**
458    * A string representation of the `true value' of one of the object's fields.
459    * For example the return value for the user table's category field would be 
460    * User. 
461    * The value returned is relative to the transaction associated with the
462    * calling thread, as set up by <TT>Database.inSession</TT>: see the remarks
463    * made about <TT>getRaw</TT>.
464    *
465    * @param name        the name of the field (<I>i.e.</I> the name of the
466    *                    column in the RDBMS and DSD)
467    * @param locale      A PoemLocale eg PoemLocale.HERE
468    * @param style       A date format
469    *
470    * @return The string the underlying RDBMS would display if asked
471    *         to show the field's value, except that reference fields are
472    *         represented by their referee's <TT>displayString()</TT> (by
473    *         default, its primary display field) rather than by its troid.  If
474    *         you want to see troids instead, use <TT>getRawString</TT>.  If
475    *         you want the field's value as an appropriate Java type like
476    *         <TT>Integer</TT>, use <TT>getRaw</TT> or <TT>getCooked</TT>---or
477    *         an equivalent, but type-safe, method derived from the DSD.
478    *
479    * @exception NoSuchColumnPoemException
480    *                if the field named doesn't exist
481    * @exception AccessPoemException
482    *                if the calling thread doesn't have read access to the
483    *                object (see <TT>assertCanRead</TT>)
484    *
485    * @see #getRawString
486    * @see #getRaw
487    * @see #getCooked
488    * @see #assertCanRead()
489    * @see #displayString
490    */
491 
492   String getCookedString(String name, PoemLocale locale, int style)
493           throws NoSuchColumnPoemException, AccessPoemException;
494 
495   /**
496    * Set the `true value' of one of the record's fields.  Like
497    * <TT>setRaw</TT>, but reference fields expect to see a
498    * <TT>Persistent</TT> representing their new referee rather than an
499    * <TT>Integer</TT> specifying its troid.  The remarks about sessions
500    * (transactions) and DSD-derived type-safe methods made for
501    * <TT>setRaw</TT> apply here too.
502    *
503    * @param name        the name of the field (<I>i.e.</I> the name of the
504    *                    column in the RDBMS and DSD)
505    *
506    * @param cooked      the new value for the field: a <TT>String</TT>,
507    *                    <TT>Boolean</TT>, <TT>Integer</TT>, <TT>Double</TT>,
508    *                    <TT>Date</TT> or, for a reference field, a
509    *                    <TT>Persistent</TT>.  If you want to pass referees as
510    *                    troids, use <TT>setRaw</TT>.  If you want to set the
511    *                    field from a string representation (<I>e.g.</I> typed
512    *                    in by the user), use <TT>setRawString</TT>.
513    *
514    * @exception NoSuchColumnPoemException
515    *                if the field named doesn't exist
516    * @exception AccessPoemException
517    *                if the calling thread doesn't have write access to the
518    *                object (see <TT>assertCanWrite</TT>)
519    * @exception ValidationPoemException
520    *                if <TT>cooked</TT> is not a valid value for the field
521    *                (<I>e.g.</I> a string is too long)
522    *
523    * @see #setRaw
524    * @see #setRawString
525    * @see #assertCanWrite()
526    */
527 
528   void setCooked(String name, Object cooked)
529           throws NoSuchColumnPoemException, ValidationPoemException,
530           AccessPoemException;
531 
532   /**
533    * The value of one of the object's fields, wrapped up with type information
534    * sufficient for rendering it.  Basically, value plus name plus type.  This
535    * is the form in which Melati's templating facilities expect to receive
536    * values for displaying them or creating input boxes.
537    *
538    * <P>
539    *
540    * If the field <TT><I>baz</I></TT> is defined in the DSD as part of a table
541    * called <TT><I>foo</I></TT>, then the table's records will be represented
542    * by an application-specialised subclass of <TT>Persistent</TT> called
543    * <TT><I>Foo</I></TT> which provides a <TT>get<I>Baz</I>Field</TT> method.
544    *
545    * @param name column name
546    * @return the Field of that name
547    * @throws NoSuchColumnPoemException if there is no column of that name
548    * @throws AccessPoemException if the current AccessToken does not grant access capability
549    */
550   Field<?> getField(String name) throws NoSuchColumnPoemException,
551           AccessPoemException;
552 
553   /**
554    * Create Fields from Columns. 
555    * 
556    * @param columns an Enumeration of Columns
557    * @return an Enumeration of Fields 
558    */
559   Enumeration<Field<?>> fieldsOfColumns(Enumeration<Column<?>> columns);
560 
561   /**
562    * The values of all the object's fields, wrapped up with type information
563    * sufficient for rendering them.
564    *
565    * @return an <TT>Enumeration</TT> of <TT>Field</TT>s
566    */
567 
568   Enumeration<Field<?>> getFields();
569 
570   /**
571    * The values of all the object's fields designated for inclusion in full
572    * record displays, wrapped up with type information sufficient for rendering
573    * them.
574    *
575    * @return an <TT>Enumeration</TT> of <TT>Field</TT>s
576    * @see DisplayLevel#record
577    */
578 
579   Enumeration<Field<?>> getRecordDisplayFields();
580 
581   /**
582    * All fields at the detailed display level in display order.
583    *
584    * @return an <TT>Enumeration</TT> of <TT>Field</TT>s
585    * @see DisplayLevel#detail
586    */
587   Enumeration<Field<?>> getDetailDisplayFields();
588 
589   /**
590    * All fields at the summary display level in display order.
591    *
592    * @return an <TT>Enumeration</TT> of <TT>Field</TT>s
593    * @see DisplayLevel#summary
594    */
595   Enumeration<Field<?>> getSummaryDisplayFields();
596 
597   /**
598    * @return an <TT>Enumeration</TT> of searchable <TT>Field</TT>s
599    */
600   Enumeration<Field<?>> getSearchCriterionFields();
601 
602   /**
603    * @return the Primary Display Column as a Field
604    */
605   Field<?> getPrimaryDisplayField();
606 
607   /**
608    * Delete the object.  Before the record is deleted from the database, POEM
609    * checks to see if it is the target of any reference fields.  What happens
610    * in this case is determined by the <TT>integrityfix</TT> setting of the
611    * referring column, unless that's overridden via the
612    * <TT>integrityFixOfColumn</TT> argument.  By default, a
613    * <TT>DeletionIntegrityPoemException</TT> is thrown, but this behaviour can
614    * be changed through the admin interface.
615    *
616    * @see IntegrityFix
617    * @see PoemThread#commit
618    *
619    * @param integrityFixOfColumn
620    *            A map from {@link Column} to {@link IntegrityFix} which says
621    *            how referential integrity is to be maintained for each column
622    *            that can refer to the object being deleted.  May be
623    *            <TT>null</TT> to mean `empty'.  If a column isn't mentioned,
624    *            the default behaviour for the column is used.  (The default 
625    *            is {@link StandardIntegrityFix#prevent}.)
626    */
627   void delete(Map<Column<?>, IntegrityFix> integrityFixOfColumn);
628 
629   /**
630    * Delete without access checks.
631    */
632   void delete_unsafe();
633 
634   /**
635    * Delete this persistent, with default integrity checks, 
636    * ie disallow deletion if object referred to by others.
637    */
638   void delete();
639 
640   /**
641    * Delete the object, with even more safety checks for referential integrity.
642    * As {@link #delete(java.util.Map)}, but waits for exclusive access to the
643    * database before doing the delete, and commits the session immediately
644    * afterwards.  
645    * <p>
646    * This used to be the only deletion entry point allowed, but
647    * now we ensure that the possible race condition involving new
648    * pointers to the deleted object created during the deletion process is
649    * covered. So it is recommended to use {@link #delete(java.util.Map)}
650    * unless you really want this functionality.
651    *
652    */
653   void deleteAndCommit(Map<Column<?>, IntegrityFix> integrityFixOfColumn)
654           throws AccessPoemException, DeletionIntegrityPoemException;
655 
656   /**
657    * Convenience method with default integrity fix. 
658    * 
659    * @throws AccessPoemException
660    * @throws DeletionIntegrityPoemException
661    */
662   void deleteAndCommit() throws AccessPoemException,
663           DeletionIntegrityPoemException;
664 
665   /**
666    * Create a new object like this one.
667    * This Persistent must not be floating.
668    * 
669    * @return A floating clone
670    */
671   Persistent duplicated() throws AccessPoemException;
672 
673   /**
674    * Create a new persistent like this one, regardless of 
675    * whether this Persistent has been written to the dbms yet.
676    * 
677    * @return A floating clone
678    */
679   Persistent duplicatedFloating() throws AccessPoemException;
680 
681   /**
682    * A string describing the object for the purposes of rendering it in lists
683    * presented to the user.  Unless overridden, this returns the value picked
684    * out by the designated `primary display column' of the table from which the
685    * object comes.  If there is no such column, the object's troid is returned
686    * (as a decimal string).
687    * 
688    * @param locale our locale
689    * @param style 
690    *      a DateFormat (only applicable to those rare objects whose summary column is a date)
691    * @return the String to display
692    * @throws AccessPoemException 
693    *         if current User does not have viewing {@link Capability}
694    */
695   String displayString(PoemLocale locale, int style)
696           throws AccessPoemException;
697 
698   /**
699    * Defaults to DateFormat.MEDIUM.
700    * @return Default String for display.
701    * 
702    * @throws AccessPoemException 
703    *         if current User does not have viewing {@link Capability}
704    */
705   String displayString(PoemLocale locale) throws AccessPoemException;
706 
707   /**
708    * @return Default String for display.
709    * 
710    * @throws AccessPoemException 
711    *         if current User does not have viewing {@link Capability}
712    */
713   String displayString() throws AccessPoemException;
714 
715   /**
716    * @return the dump String
717    */
718   String dump();
719 
720   /**
721    * Dump to a PrintStream.
722    * @param p the PrintStream to dump to
723    */
724   void dump(PrintStream p);
725 
726   /**
727    * Called after this persistent is written to the database
728    * on being inserted or modified.
729    * <p>
730    * This is called after postInsert() or postModify().
731    * <p>
732    * This is low level and there is a limit to what you can
733    * do here without causing infinitely recursive calls.
734    */
735   void postWrite();
736 
737   /**
738    * Called after this persistent is written to the database
739    * for the first time.
740    * <p>
741    * This is low level and there is a limit to what you can
742    * do here without causing infinitely recursive calls.
743    */
744   void postInsert();
745 
746   /**
747    * Called after this persistent is updated and written to the
748    * database replacing the existing record it represents.
749    * <p>
750    * Not called when it is written to the database for the
751    * first time.
752    * <p>
753    * This is low level and there is a limit to what you can
754    * do here without causing infinitely recursive calls.
755    */
756   void postModify();
757 
758   /**
759    * Optionally called before an instance is edited by the user.
760    * <p>
761    * See {@link #postEdit(boolean)} for additional comments.
762    * However, it is not called when a newly created row is
763    * edited.
764    */
765   void preEdit();
766 
767   /**
768    * Optionally called after this instance is edited by a user.
769    * <p>
770    * Unlike {@link #postModify()} and {@link #postInsert()} this
771    * is not called during write down but can be called by
772    * applications after individual field edits by the user
773    * have been reflected in the instance.
774    * <p>
775    * It can be be overridden to enforce data model constraints
776    * such as validity of columns relative to other columns.
777    * These will be enforced when the admin system is used.
778    * <p>
779    * This is a higher level method than {@link #postModify()}
780    * so is less likely to lead to infinite recursion or other
781    * such problems.
782    * <p>
783    * Sorry for the lack of signature consistency with the
784    * lower level methods but I got tired of having to call
785    * my own application specific common method.
786    *
787    * @param creating Are we in the process of creating a new record?
788    */
789   void postEdit(boolean creating);
790 
791   /**
792    * @return the dirty
793    */
794   boolean isDirty();
795   
796   /**
797    * @param dirty the dirty to set
798    */
799   void setDirty(boolean dirty);
800 
801 
802 }
803