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