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