Coverage Report - org.melati.poem.Persistent
 
Classes in this File Line Coverage Branch Coverage Complexity
Persistent
N/A
N/A
1
 
 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