|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.melati.poem.transaction.Transactioned org.melati.poem.JdbcPersistent
public class JdbcPersistent
The object representing a single table row; this is the PO in POEM!
Instances are also used to represent selection criteria.
Field Summary |
---|
Fields inherited from class org.melati.poem.transaction.Transactioned |
---|
valid |
Constructor Summary | |
---|---|
JdbcPersistent()
Constructor. |
|
JdbcPersistent(JdbcTable table,
Integer troid)
Constructor. |
|
JdbcPersistent(String tableName,
String troidString)
Constructor. |
Method Summary | |
---|---|
void |
assertCanCreate()
|
void |
assertCanCreate(AccessToken token)
Check that you have create access to the object. |
void |
assertCanDelete()
|
void |
assertCanDelete(AccessToken token)
Check that you have delete access to the object. |
void |
assertCanRead()
|
void |
assertCanRead(AccessToken token)
Check that you have read access to the object. |
void |
assertCanWrite()
|
void |
assertCanWrite(AccessToken token)
Check that you have write access to the object. |
protected Object |
clone()
|
protected void |
commit(Transaction transaction)
Previously deletion was treated as non-rollbackable, as deleteAndCommit was the only deletion mechanism. |
protected String |
countMatchSQL(boolean includeDeleted,
boolean excludeUnselectable)
Return a SELECT query to count rows matching criteria represented by this object. |
void |
delete_unsafe()
Delete without access checks. |
void |
delete()
Delete this persistent, with default integrity checks, ie disallow deletion if object referred to by others. |
void |
delete(Map<Column,IntegrityFix> integrityFixOfColumn)
Delete the object. |
void |
deleteAndCommit()
Convenience method with default integrity fix. |
void |
deleteAndCommit(Map<Column,IntegrityFix> integrityFixOfColumn)
Delete the object, with even more safety checks for referential integrity. |
protected void |
deleteLock(SessionToken sessionToken)
|
String |
displayString()
|
String |
displayString(PoemLocale locale)
Defaults to DateFormat.MEDIUM. |
String |
displayString(PoemLocale locale,
int style)
A string describing the object for the purposes of rendering it in lists presented to the user. |
String |
dump()
|
void |
dump(PrintStream p)
Dump to a PrintStream. |
Persistent |
duplicated()
Create a new object like this one. |
Persistent |
duplicatedFloating()
Create a new persistent like this one, regardless of whether this Persistent has been written to the dbms yet. |
boolean |
equals(Object object)
|
void |
existenceLock()
Lock without actually reading. |
protected void |
existenceLock(SessionToken sessionToken)
|
Enumeration<Field> |
fieldsOfColumns(Enumeration<Column> columns)
Create Fields from Columns. |
protected String |
fromClause()
Return an SQL FROM clause for use when selecting rows using criteria represented by this object. |
protected Capability |
getCanDelete()
The capability required for deleting the object. |
protected Capability |
getCanRead()
The capability required for reading the object's field values. |
protected Capability |
getCanSelect()
The capability required to select the object. |
protected Capability |
getCanWrite()
The capability required for writing the object's field values. |
Treeable[] |
getChildren()
|
Object |
getCooked(String name)
The `true value' of one of the object's fields. |
String |
getCookedString(String name,
PoemLocale locale,
int style)
A string representation of the `true value' of one of the object's fields. |
Database |
getDatabase()
|
Enumeration<Field> |
getDetailDisplayFields()
All fields at the detailed display level in display order. |
Field |
getField(String name)
The value of one of the object's fields, wrapped up with type information sufficient for rendering it. |
Enumeration<Field> |
getFields()
The values of all the object's fields, wrapped up with type information sufficient for rendering them. |
String |
getName()
NOTE This will be overridden if the persistent has a field called name. |
Field |
getPrimaryDisplayField()
|
Object |
getRaw(String name)
The `identifying value' of one of the object's fields. |
String |
getRawString(String name)
A string representation of the `identifying value' of one of the object's fields. |
boolean |
getReadable()
|
Enumeration<Field> |
getRecordDisplayFields()
The values of all the object's fields designated for inclusion in full record displays, wrapped up with type information sufficient for rendering them. |
Enumeration<Field> |
getSearchCriterionFields()
|
Enumeration<Field> |
getSummaryDisplayFields()
All fields at the summary display level in display order. |
Table |
getTable()
The Table from which the object comes, complete with metadata. |
Integer |
getTroid()
The object's troid. |
int |
hashCode()
|
void |
invalidate()
Mark as invalid. |
boolean |
isDirty()
|
protected void |
load(Transaction transaction)
Called if not uptodate. |
void |
makePersistent()
A convenience method to create this Persistent. |
void |
postEdit(boolean creating)
Optionally called after this instance is edited by a user. |
void |
postInsert()
Called after this persistent is written to the database for the first time. |
void |
postModify()
Called after this persistent is updated and written to the database replacing the existing record it represents. |
void |
postWrite()
Called after this persistent is written to the database on being inserted or modified. |
void |
preEdit()
Optionally called before an instance is edited by the user. |
protected void |
readLock()
Check if we may read this object and then lock it. |
protected void |
readLock(SessionToken sessionToken)
|
protected void |
readLock(Transaction transaction)
This is just to make this method available to Table. |
protected void |
rollback(Transaction transaction)
|
void |
setCooked(String name,
Object cooked)
Set the `true value' of one of the record's fields. |
void |
setDirty(boolean dirty)
|
void |
setRaw(String name,
Object raw)
Set the `identifying value' of one of the record's fields. |
void |
setRawString(String name,
String string)
Set the `identifying value' of one of the record's fields from a string representation. |
boolean |
statusExistent()
|
boolean |
statusNonexistent()
|
String |
toString()
A string briefly describing the object for diagnostic purposes. |
Integer |
troid()
Get the troid without access checking. |
protected boolean |
upToDate(Transaction transaction)
Whether we are up to date with respect to current Transaction. |
protected void |
writeDown(Transaction transaction)
Write the persistent to the database if this might be necessary. |
protected void |
writeLock()
Check if we may write to this object and then lock it. |
protected void |
writeLock(SessionToken sessionToken)
|
protected void |
writeLock(Transaction transaction)
Get a write lock on the given object if we do not already have one. |
Methods inherited from class org.melati.poem.transaction.Transactioned |
---|
markValid, reset, setTransactionPool, transactionPool, unSee |
Methods inherited from class java.lang.Object |
---|
finalize, getClass, notify, notifyAll, wait, wait, wait |
Constructor Detail |
---|
public JdbcPersistent()
public JdbcPersistent(JdbcTable table, Integer troid)
table
- the table of the Persistenttroid
- its Table Row Object Idpublic JdbcPersistent(String tableName, String troidString)
tableName
- String name of a tabletroidString
- String integer representationMethod Detail |
---|
public final boolean statusNonexistent()
statusNonexistent
in interface Persistent
Persistent.statusNonexistent()
public final boolean statusExistent()
statusExistent
in interface Persistent
Persistent.statusExistent()
protected void load(Transaction transaction)
load
in class Transactioned
load(org.melati.poem.transaction.Transaction)
protected boolean upToDate(Transaction transaction)
Return the inherited validity flag. Whether this instance is up-to-date.
This is a hook to enable subtypes to define under what circumstances an instance needs to be reloaded when it is marked as invalid, however the two known subtypes just return the inherited valid flag.
upToDate
in class Transactioned
upToDate(org.melati.poem.transaction.Transaction)
protected void writeDown(Transaction transaction)
It may be necessary if field values have been set since we last did a write i.e. this persistent is dirty. It will not be necessary if this persistent is deleted. An exception will occur if it does not exist in the database.
writeDown
in class Transactioned
protected void writeLock(Transaction transaction)
This will block until no other transactions have write locks on the object before claiming the next write lock. Then it will block until none have read locks.
Finally it calls Transactioned.ensureValid(Transaction)
.
writeLock
in class Transactioned
Transactioned.writeLock(org.melati.poem.transaction.Transaction)
protected void readLock(Transaction transaction)
readLock
in class Transactioned
protected void commit(Transaction transaction)
commit
in class Transactioned
commit(org.melati.poem.transaction.Transaction)
protected void rollback(Transaction transaction)
rollback
in class Transactioned
public void makePersistent()
makePersistent
in interface Persistent
Persistent.makePersistent()
public final Table getTable()
getTable
in interface Persistent
Persistent.getTable()
public final Database getDatabase()
getDatabase
in interface Persistent
Persistent.getDatabase()
public final Integer troid()
Persistable
troid
in interface Persistable
Persistable.troid()
public final Integer getTroid() throws AccessPoemException
getTroid
in interface Persistable
AccessPoemException
- if assertCanRead failsTable.getObject(java.lang.Integer)
,
assertCanRead()
protected void existenceLock(SessionToken sessionToken)
protected void readLock(SessionToken sessionToken) throws AccessPoemException
AccessPoemException
protected void writeLock(SessionToken sessionToken) throws AccessPoemException
AccessPoemException
protected void deleteLock(SessionToken sessionToken) throws AccessPoemException
AccessPoemException
public void existenceLock()
existenceLock
in interface Persistent
Persistent.existenceLock()
protected void readLock() throws AccessPoemException
AccessPoemException
- if current AccessToken does not give read Capabilityprotected void writeLock() throws AccessPoemException
AccessPoemException
- if current AccessToken does not give write Capabilityprotected Capability getCanRead()
NOTE If a canRead column is defined then it will override this method.
assertCanRead(org.melati.poem.AccessToken)
public void assertCanRead(AccessToken token) throws AccessPoemException
Although this check can in theory be quite time-consuming, in practice this isn't a problem, because the most recent access token for which the check succeeded is cached; repeat accesses from within the same transaction are therefore quick.
Application programmers can override this method to implement their own programmatic access policies. For instance, POEM's own TableInfo class overrides it with an empty method in order to disable all read protection on TableInfo objects. More interestingly, you could implement a check that depends on the values of the object's fields: for example, you could allow read access to an invoice record to its issuing and receiving parties.
assertCanRead
in interface Persistent
token
- the access token on the basis of which readability is
being claimed
AccessPoemException
- if the check failsPersistent.assertCanRead(org.melati.poem.AccessToken)
public final void assertCanRead() throws AccessPoemException
assertCanRead
in interface Persistent
AccessPoemException
- if current accessToken does not grant read capabilityPersistent.assertCanRead()
public final boolean getReadable()
getReadable
in interface Persistent
Persistent.getReadable()
protected Capability getCanWrite()
NOTE If a canWrite column is defined then it will override this method.
assertCanWrite(org.melati.poem.AccessToken)
public void assertCanWrite(AccessToken token) throws AccessPoemException
assertCanWrite
in interface Persistent
AccessPoemException
Persistent.assertCanWrite(org.melati.poem.AccessToken)
public final void assertCanWrite() throws AccessPoemException
assertCanWrite
in interface Persistent
AccessPoemException
- if current accessToken does not grant wraite capabilityPersistent.assertCanWrite()
protected Capability getCanDelete()
NOTE If a canDelete column is defined then it will override this method.
assertCanDelete(org.melati.poem.AccessToken)
public void assertCanDelete(AccessToken token) throws AccessPoemException
assertCanDelete
in interface Persistent
AccessPoemException
Persistent.assertCanDelete(org.melati.poem.AccessToken)
public final void assertCanDelete() throws AccessPoemException
assertCanDelete
in interface Persistent
AccessPoemException
- if current accessToken does not grant delete capabilityPersistent.assertCanDelete()
protected Capability getCanSelect()
Any persistent which has a canSelect field will override this method.
There is no assertCanSelect()
yet because I don't understand
this stale token stuff!
public void assertCanCreate(AccessToken token)
Application programmers can override this method to implement their own programmatic access policies.
assertCanCreate
in interface Persistent
Persistent.assertCanCreate(org.melati.poem.AccessToken)
public final void assertCanCreate() throws AccessPoemException
assertCanCreate
in interface Persistent
AccessPoemException
- if current accessToken does not grant create capabilityPersistent.assertCanCreate()
public Object getRaw(String name) throws NoSuchColumnPoemException, AccessPoemException
If the field baz is defined in the DSD as part of a table called foo, then the table's records will be represented by an application-specialised subclass of Persistent called Foo which provides a typed getBaz method. So the easiest way to be sure of your types is to predeclare any fields you use in the DSD, use the typed field-access methods, and let the compiler take the strain. When working with generic Persistents, you probably want to use getField.
The value returned is relative to the transaction associated with the calling thread, as set up by Database.inSession. This means that you never see the value of a field change in your transaction because of another transaction's activities, unless you do a PoemThread.commit() or a PoemThread.rollback(). If you need to, you can store a Persistent in a permanent data structure and access it in different sessions over time---or even from concurrently running sessions, though this may slow down access checking; each transaction will see the value it expects.
getRaw
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)
NoSuchColumnPoemException
- if the field named doesn't exist
AccessPoemException
- if the calling thread doesn't have read access to the
object (see assertCanRead)Persistent.getRaw(java.lang.String)
public final String getRawString(String name) throws AccessPoemException, NoSuchColumnPoemException
getRawString
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)
AccessPoemException
- if the calling thread doesn't have read access to the
object (see assertCanRead)
NoSuchColumnPoemException
- if the field named doesn't existPersistent.getRawString(java.lang.String)
public void setRaw(String name, Object raw) throws NoSuchColumnPoemException, AccessPoemException, ValidationPoemException
If the field baz is defined in the DSD as part of a table called foo, then the table's records will be represented by an application-specialised subclass of Persistent called Foo which provides a typed setBaz method. So the easiest way to be sure of your types is to predeclare any fields you use in the DSD, use the typed field-access methods, and let the compiler take the strain. When working with generic Persistents, you probably mean setRawString anyway.
The change you make to the field's value will only be visible to the calling thread, until it successfully completes the task started by Database.inSession, or does an explicit PoemThread.commit(). Up to that point the change can be undone by calling PoemThread.rollback(), and will be undone automatically if the task terminates with an uncaught exception.
In fact, your changes are not written down to the database, even relative to an uncommitted transaction, until it's actually necessary. So multiple calls to setRaw and relatives will not cause multiple SQL UPDATEs to be issued.
setRaw
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)raw
- The new value for the field: a String,
Boolean, Integer, Double or
Date as appropriate. If the field is a
reference field: an Integer giving the troid
of the referee. If you want to pass referees as actual
Persistents, use setCooked. If you
want to set the field from a string representation
(e.g. typed in by the user), use
setRawString.
NoSuchColumnPoemException
- if the field named doesn't exist
AccessPoemException
- if the calling thread doesn't have write access to the
object (see assertCanWrite)
ValidationPoemException
- if raw is not a valid value for the field
(e.g. a string is too long)Persistent.setRaw(java.lang.String, java.lang.Object)
public final void setRawString(String name, String string) throws NoSuchColumnPoemException, AccessPoemException, ParsingPoemException, ValidationPoemException
setRawString
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)string
- A string that will be parsed to obtain the new value
for the field. If it's a reference field, this should
be a decimal representation of the referee's troid. If
you want to set fields to values defined by appropriate
Java types, use setRaw or setCooked.
NoSuchColumnPoemException
- if the field named doesn't exist
AccessPoemException
- if the calling thread doesn't have write access to the
object (see assertCanWrite)
ParsingPoemException
- if string doesn't parse as a value of the
appropriate type
ValidationPoemException
- if string parses to an invalid value for the field
(e.g. it's too wide)Persistent.setRawString(java.lang.String, java.lang.String)
public Object getCooked(String name) throws NoSuchColumnPoemException, AccessPoemException
The value returned is relative to the transaction associated with the calling thread, as set up by Database.inSession: see the remarks made about getRaw.
The easiest way to be sure of your types is to predeclare any fields you use in the DSD, or use getField. Again, see the remarks made about getRaw.
getCooked
in interface Persistent
NoSuchColumnPoemException
- if the field named doesn't exist
AccessPoemException
- if the calling thread doesn't have read access to the
object (see assertCanRead)Persistent.getCooked(java.lang.String)
public final String getCookedString(String name, PoemLocale locale, int style) throws NoSuchColumnPoemException, AccessPoemException
getCookedString
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)locale
- A PoemLocale eg PoemLocale.HEREstyle
- A date format
NoSuchColumnPoemException
- if the field named doesn't exist
AccessPoemException
- if the calling thread doesn't have read access to the
object (see assertCanRead)Persistent.getCookedString(java.lang.String, org.melati.poem.PoemLocale, int)
public void setCooked(String name, Object cooked) throws NoSuchColumnPoemException, ValidationPoemException, AccessPoemException
setCooked
in interface Persistent
name
- the name of the field (i.e. the name of the
column in the RDBMS and DSD)cooked
- the new value for the field: a String,
Boolean, Integer, Double,
Date or, for a reference field, a
Persistent. If you want to pass referees as
troids, use setRaw. If you want to set the
field from a string representation (e.g. typed
in by the user), use setRawString.
NoSuchColumnPoemException
- if the field named doesn't exist
ValidationPoemException
- if cooked is not a valid value for the field
(e.g. a string is too long)
AccessPoemException
- if the calling thread doesn't have write access to the
object (see assertCanWrite)Persistent.setCooked(java.lang.String, java.lang.Object)
public final Field getField(String name) throws NoSuchColumnPoemException, AccessPoemException
If the field baz is defined in the DSD as part of a table called foo, then the table's records will be represented by an application-specialised subclass of Persistent called Foo which provides a getBazField method.
getField
in interface Persistent
name
- column name
NoSuchColumnPoemException
- if there is no column of that name
AccessPoemException
- if the current AccessToken does not grant access capabilityPersistent.getField(java.lang.String)
public Enumeration<Field> fieldsOfColumns(Enumeration<Column> columns)
fieldsOfColumns
in interface Persistent
columns
- an Enumeration of Columns
Persistent.fieldsOfColumns(java.util.Enumeration)
public Enumeration<Field> getFields()
getFields
in interface Persistent
Persistent.getFields()
public Enumeration<Field> getRecordDisplayFields()
getRecordDisplayFields
in interface Persistent
Persistent.getRecordDisplayFields()
public Enumeration<Field> getDetailDisplayFields()
getDetailDisplayFields
in interface Persistent
Persistent.getDetailDisplayFields()
public Enumeration<Field> getSummaryDisplayFields()
getSummaryDisplayFields
in interface Persistent
Persistent.getSummaryDisplayFields()
public Enumeration<Field> getSearchCriterionFields()
getSearchCriterionFields
in interface Persistent
Persistent.getSearchCriterionFields()
public Field getPrimaryDisplayField()
getPrimaryDisplayField
in interface Persistent
Persistent.getPrimaryDisplayField()
public void delete(Map<Column,IntegrityFix> integrityFixOfColumn)
delete
in interface Persistent
integrityFixOfColumn
- A map from Column
to IntegrityFix
which says
how referential integrity is to be maintained for each column
that can refer to the object being deleted. May be
null to mean `empty'. If a column isn't mentioned,
the default behaviour for the column is used. (The default
is StandardIntegrityFix.prevent
.)Persistent.delete(java.util.Map)
public void delete_unsafe()
delete_unsafe
in interface Persistent
Persistent.delete_unsafe()
public final void delete()
delete
in interface Persistent
Persistent.delete()
public void deleteAndCommit(Map<Column,IntegrityFix> integrityFixOfColumn) throws AccessPoemException, DeletionIntegrityPoemException
Persistent.delete(java.util.Map)
, but waits for exclusive access to the
database before doing the delete, and commits the session immediately
afterwards.
This used to be the only deletion entry point allowed, but
now we ensure that the possible race condition involving new
pointers to the deleted object created during the deletion process is
covered. So it is recommended to use Persistent.delete(java.util.Map)
unless you really want this functionality.
deleteAndCommit
in interface Persistent
AccessPoemException
DeletionIntegrityPoemException
Persistent.deleteAndCommit(java.util.Map)
public final void deleteAndCommit() throws AccessPoemException, DeletionIntegrityPoemException
deleteAndCommit
in interface Persistent
AccessPoemException
DeletionIntegrityPoemException
Persistent.deleteAndCommit()
public Persistent duplicated() throws AccessPoemException
duplicated
in interface Persistent
AccessPoemException
Persistent.duplicated()
public Persistent duplicatedFloating() throws AccessPoemException
duplicatedFloating
in interface Persistent
AccessPoemException
Persistent.duplicatedFloating()
public String toString()
toString
in class Object
Object.toString()
public String displayString(PoemLocale locale, int style) throws AccessPoemException
displayString
in interface Persistent
locale
- our localestyle
- a DateFormat (only applicable to those rare objects whose summary column is a date)
AccessPoemException
- if current User does not have viewing Capability
Persistent.displayString(org.melati.poem.PoemLocale, int)
public String displayString(PoemLocale locale) throws AccessPoemException
displayString
in interface Persistent
AccessPoemException
- if current User does not have viewing Capability
Persistent.displayString(org.melati.poem.PoemLocale)
public String displayString() throws AccessPoemException
displayString
in interface Persistent
AccessPoemException
- if current User does not have viewing Capability
Persistent.displayString()
public final int hashCode()
hashCode
in class Object
Object.hashCode()
public final boolean equals(Object object)
equals
in class Object
Object.equals(java.lang.Object)
public void invalidate()
invalidate
in class Transactioned
Transactioned.invalidate()
protected Object clone()
clone
in class Object
Object.clone()
public String dump()
dump
in interface Persistent
Persistent.dump()
public void dump(PrintStream p)
dump
in interface Persistent
p
- the PrintStream to dump toPersistent.dump(java.io.PrintStream)
public void postWrite()
This is called after postInsert() or postModify().
This is low level and there is a limit to what you can do here without causing infinitely recursive calls.
postWrite
in interface Persistent
Persistent.postWrite()
public void postInsert()
This is low level and there is a limit to what you can do here without causing infinitely recursive calls.
postInsert
in interface Persistent
Persistent.postInsert()
public void postModify()
Not called when it is written to the database for the first time.
This is low level and there is a limit to what you can do here without causing infinitely recursive calls.
postModify
in interface Persistent
Persistent.postModify()
public void preEdit()
See Persistent.postEdit(boolean)
for additional comments.
However, it is not called when a newly created row is
edited.
preEdit
in interface Persistent
Persistent.preEdit()
public void postEdit(boolean creating)
Unlike Persistent.postModify()
and Persistent.postInsert()
this
is not called during write down but can be called by
applications after individual field edits by the user
have been reflected in the instance.
It can be be overridden to enforce data model constraints such as validity of columns relative to other columns. These will be enforced when the admin system is used.
This is a higher level method than Persistent.postModify()
so is less likely to lead to infinite recursion or other
such problems.
Sorry for the lack of signature consistency with the lower level methods but I got tired of having to call my own application specific common method.
postEdit
in interface Persistent
creating
- Are we in the process of creating a new record?Persistent.postEdit(boolean)
protected String countMatchSQL(boolean includeDeleted, boolean excludeUnselectable)
includeDeleted
- whether to include soft deleted recordsexcludeUnselectable
- Whether to append unselectable exclusion SQL
protected String fromClause()
By default just the table name is returned, quoted as necessary for the DBMS.
Subtypes must ensure the result is compatible with the
result of #appendWhereClause(StringBuffer, JdbcPersistent)
.
public Treeable[] getChildren()
getChildren
in interface Treeable
public String getName()
getName
in interface Treeable
Treeable.getName()
public boolean isDirty()
isDirty
in interface Persistent
public void setDirty(boolean dirty)
setDirty
in interface Persistent
dirty
- the dirty to set
|
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |