arlut.csd.ganymede
Class DBEditObject

java.lang.Object
  |
  +--arlut.csd.ganymede.DBObject
        |
        +--arlut.csd.ganymede.DBEditObject
All Implemented Interfaces:
db_object, FieldType, ObjectStatus, java.rmi.Remote
Direct Known Subclasses:
adminPersonaCustom, eventCustom, objectEventCustom, ownerCustom, permCustom, taskCustom

public class DBEditObject
extends DBObject
implements ObjectStatus, FieldType

DBEditObject is the main base class that is subclassed by individual application object types to provide editing and management intelligence. Both static and instance methods are defined in DBEditObject which can be subclassed to provide object management intelligence.

A instance of DBEditObject is a copy of a DBObject that has been exclusively checked out from the main database so that a DBSession can edit the fields of the object. The DBEditObject class keeps track of the changes made to fields, keeping things properly synchronized with unique field name spaces.

Generally, DBEditObjects are obtained in the context of a DBEditSet transaction object. When the DBEditSet is committed, a new DBObject is created from the contents of the DBEditObject and is made to replace the original object in the DBStore. If the EditSet is aborted, the DBEditObject is dropped.

There is one case, however, in which a DBEditObject will be present in the server outside of a DBEditSet context, and that is the DBEditObject instance used for the DBObjectBase's objectHook customization object. In this case, a DBEditObject of the appropriate subclass is created using the first constructor variant. A wide variety of methods in the server will make method calls on the DBObjectBase objectHook to allow a custom DBEditObject subclass to customize the server's behavior. Such methods are labeled *PSEUDOSTATIC*, which means that those methods are designed not to examine or report on the internal state of the objectHook, but rather are meant to operate based only on parameters passed into the method. These methods are PSEUDOSTATIC rather than static because if they were true static methods, every place in the server where such methods are called would have to use the relatively cumbersome Java Reflection API rather than being able to call methods on a DBEditObject instance.

See the DBEditObject subclassing guide for more information generally on DBEditObject customization.

IMPORTANT PROGRAMMING NOTE!: It is critical that synchronized methods in DBEditObject and in subclasses thereof do not call synchronized methods in DBSession, as there is a strong possibility of nested monitor deadlocking.


Field Summary
static int ADDELEMENT
           
static int ADDELEMENTS
           
private  arlut.csd.Util.booleanSemaphore commitSemaphore
          true if this object has had its commitPhase1() method called, but has not yet had its commitPhase2() or release() methods called.
(package private) static boolean debug
           
static int DELELEMENT
           
static int DELELEMENTS
           
protected  boolean deleting
          true if the object is in the middle of carrying out deletion logic..
 arlut.csd.ganymede.DBEditSet editset
          transaction that this object has been checked out in care of.
static int FIRSTOP
           
static int LASTOP
           
static java.util.Date maxDate
           
static java.util.Date minDate
           
protected  arlut.csd.ganymede.DBObject original
          Unless this DBEditObject was newly created, we'll have a reference to the original DBObject which is currently registered in the DBStore.
static int SETELEMENT
           
static int SETPASSAPACHEMD5
           
static int SETPASSCRYPT
           
static int SETPASSMD5
           
static int SETPASSPLAIN
           
static int SETPASSWINHASHES
           
static int SETVAL
           
(package private)  byte status
          tracks this object's editing status.
(package private)  boolean stored
          true if the object has a version currently stored in the DBStore
 
Fields inherited from class arlut.csd.ganymede.DBObject
debugEmit, fieldAry, gSession, myInvid, next, objectBase, permCacheAry, shadowObject
 
Fields inherited from interface arlut.csd.ganymede.ObjectStatus
CREATING, DELETING, DROPPING, EDITING
 
Fields inherited from interface arlut.csd.ganymede.FieldType
BOOLEAN, DATE, FIRSTFIELD, FLOAT, INVID, IP, LASTFIELD, NUMERIC, PASSWORD, PERMISSIONMATRIX, STRING
 
Constructor Summary
DBEditObject(arlut.csd.ganymede.DBObjectBase base)
          Dummy constructor, is responsible for creating a DBEditObject strictly for the purpose of having a handle to call our pseudostatic customization methods on.
DBEditObject(arlut.csd.ganymede.DBObjectBase objectBase, arlut.csd.ganymede.Invid invid, arlut.csd.ganymede.DBEditSet editset)
          Creation constructor, is responsible for creating a new editable object with all fields listed in the DBObjectBaseField instantiated but undefined.
DBEditObject(arlut.csd.ganymede.DBObject original, arlut.csd.ganymede.DBEditSet editset)
          Check-out constructor, used by DBObject.createShadow() to pull out an object for editing.
 
Method Summary
 boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject, short targetFieldID)
          This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
 boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject, short targetFieldID, arlut.csd.ganymede.DBObject sourceObject, short sourceFieldID, arlut.csd.ganymede.GanymedeSession gsession)
          This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
 boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject, short targetFieldID, arlut.csd.ganymede.GanymedeSession gsession)
          This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
 boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject object, short fieldID)
          This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
 boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject targetObject, short targetFieldID, arlut.csd.ganymede.DBObject sourceObject, short sourceFieldID, arlut.csd.ganymede.GanymedeSession gsession)
          This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
 boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject object, short fieldID, arlut.csd.ganymede.GanymedeSession gsession)
          This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.
private  arlut.csd.ganymede.ReturnVal attemptBackLinkClear(boolean local)
          This method is used to find all objects which point to us through non-symmetric links, edit them, and break the link.
 boolean canBeInactivated()
          Customization method to verify whether this object type has an inactivation mechanism.
 boolean canClone(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject object)
          Customization method to verify whether the user has permission to clone a given object.
 boolean canCloneField(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject object, arlut.csd.ganymede.DBField field)
          Customization method to verify whether a specific field in object should be cloned using the basic field-clone logic.
 boolean canCreate(arlut.csd.ganymede.Session session)
          Customization method to verify whether the user has permission to create an instance of this object type.
 boolean canInactivate(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBEditObject object)
          Customization method to verify whether the user has permission to inactivate a given object.
 boolean canRead(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject object)
          Customization method to verify whether the user has permission to view a given object.
 arlut.csd.ganymede.ReturnVal canRemove(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject object)
          Customization method to verify whether the user has permission to remove a given object.
 boolean canSeeField(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBField field)
          Customization method to verify whether the user should be able to see a specific field in a given object.
 boolean canWrite(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject object)
          Customization method to verify whether the user has permission to edit a given object.
 boolean checkNewField(short fieldID)
          This method is used to make sure that the built-in fields that the server assumes will always be present in any editable object will be in place.
(package private)  java.util.Hashtable checkpoint()
          Returns a hashtable mapping Short field id's to their current value, used by the DBEditSet intra-transaction checkpointing logic to capture this object's state at a given time.
 boolean choiceListHasExceptions(arlut.csd.ganymede.DBField field)
          This method is used to tell the client whether the list of options it gets back for a field can be taken out of the cache.
private  arlut.csd.ganymede.ReturnVal clearBackLink(arlut.csd.ganymede.Invid remote, boolean local)
          This method is called by attemptBackLinkClear(), and is responsible for checking the object with Invid remote out for editing, and clearing our own Invid out of all of the remote object's fields.
 arlut.csd.ganymede.ReturnVal cloneFromObject(arlut.csd.ganymede.DBSession session, arlut.csd.ganymede.DBObject origObj, boolean local)
          Hook to allow the cloning of an object.
 arlut.csd.ganymede.ReturnVal commitPhase1()
          This method performs verification for the first phase of the two-phase commit algorithm.
 void commitPhase2()
          This method is a hook for subclasses to override to pass the phase-two commit command to external processes.
 arlut.csd.ganymede.ReturnVal consistencyCheck(arlut.csd.ganymede.DBObject object)
          Customization method to verify overall consistency of a DBObject.
 arlut.csd.ganymede.ReturnVal createNewEmbeddedObject(arlut.csd.ganymede.InvidDBField field)
          Hook to have this object create a new embedded object in the given field.
 java.lang.String diff()
          This method is used to generate a String describing the difference between the current state of the DBEditObject and the original object's state.
 boolean excludeSelected(arlut.csd.ganymede.db_field field1, arlut.csd.ganymede.db_field field2)
          This method returns true if field1 should not show any choices that are currently selected in field2, where both field1 and field2 are fields in this object.
 boolean fieldRequired(arlut.csd.ganymede.DBObject object, short fieldid)
          Customization method to control whether a specified field is required to be defined at commit time for a given object.
 arlut.csd.ganymede.ReturnVal finalizeAddElement(arlut.csd.ganymede.DBField field, java.lang.Object value)
          This method allows the DBEditObject to have executive approval of any vector add operation, and to take any special actions in reaction to the add..
 arlut.csd.ganymede.ReturnVal finalizeAddElements(arlut.csd.ganymede.DBField field, java.util.Vector submittedValues)
          This method allows the DBEditObject to have executive approval of any vector-vector add operation, and to take any special actions in reaction to the add..
 arlut.csd.ganymede.ReturnVal finalizeDeleteElement(arlut.csd.ganymede.DBField field, int index)
          This method allows the DBEditObject to have executive approval of any vector delete operation, and to take any special actions in reaction to the delete..
 arlut.csd.ganymede.ReturnVal finalizeDeleteElements(arlut.csd.ganymede.DBField field, java.util.Vector valuesToDelete)
          This method allows the DBEditObject to have executive approval of any vector-vector removal operation, and to take any special actions in reaction to the removal..
 void finalizeInactivate(boolean success)
          This method is to be called by the custom DBEditObject inactivate() logic when the inactivation is performed so that logging can be done.
protected  void finalizeReactivate(boolean success)
          This method is to be called by the custom DBEditObject reactivate() logic when the reactivation is performed so that logging can be done.
 arlut.csd.ganymede.ReturnVal finalizeRemove(boolean success)
          This method handles Ganymede-internal deletion logic for this object type.
 arlut.csd.ganymede.ReturnVal finalizeSetElement(arlut.csd.ganymede.DBField field, int index, java.lang.Object value)
          This method allows the DBEditObject to have executive approval of any vector set operation, and to take any special actions in reaction to the set..
 arlut.csd.ganymede.ReturnVal finalizeSetValue(arlut.csd.ganymede.DBField field, java.lang.Object value)
          This method allows the DBEditObject to have executive approval of any scalar set operation, and to take any special actions in reaction to the set.
 arlut.csd.ganymede.DBEditSet getEditSet()
          Returns the transaction object owning this object, or null if an unowned data object.
 java.util.Vector getEmailTargets(arlut.csd.ganymede.DBObject object)
          This method provides a hook to allow custom DBEditObject subclasses to return a Vector of Strings comprising a list of addresses to be notified above and beyond the normal owner group notification when the given object is changed in a transaction.
 java.lang.String getLabel()
          Returns the primary label of this object..
 java.lang.String getLabelHook(arlut.csd.ganymede.DBObject object)
          Hook to allow intelligent generation of labels for DBObjects of this type.
 arlut.csd.ganymede.DBObject getOriginal()
          Returns the original version of the object that we were created to edit.
 arlut.csd.ganymede.DBSession getSession()
          Returns the DBSession that this object is checked out in care of.
 byte getStatus()
          Returns a code indicating whether this object is being created, edited, or deleted.
 java.lang.Object getVirtualValue(arlut.csd.ganymede.DBField field)
          This method provides a hook to return interposed values for fields that have their data massaged by a DBEditObject subclass.
 boolean grantOwnership(arlut.csd.ganymede.GanymedeSession gSession, arlut.csd.ganymede.DBObject object)
          Hook to allow subclasses to grant ownership privileges to a given object.
 boolean hasEmailTarget(arlut.csd.ganymede.DBObject object)
          This method provides a hook to allow custom DBEditObject subclasses to indicate that the given object is interested in receiving notification when changes involving it occur, and can provide one or more addresses for such notification to go to.
 arlut.csd.ganymede.ReturnVal inactivate()
          This method handles inactivation logic for this object type.
 arlut.csd.ganymede.ReturnVal initializeNewObject()
          Initializes a newly created DBEditObject.
 boolean instantiateNewField(short fieldID)
          This method provides a hook that can be used to indicate whether a field that is defined in this object's field dictionary should be newly instantiated in this particular object.
protected  arlut.csd.ganymede.GanymedeSession internalSession()
          Convenience method for our customization subclasses, returns a reference to the server's internal 'supergash' session if a DBEditObject subclass needs to do queries, etc., on the server internally.
 boolean isCommitting()
          This method returns true if this object has already gone through phase 1 of the commit process, which requires the DBEditObject not to accept further changes.
 boolean isDateLimited(arlut.csd.ganymede.DBField field)
          This method provides a hook that a DBEditObject subclass can use to indicate that a given DateDBField has a restricted range of possibilities.
 boolean isDeleting()
          This method returns true if this DBEditObject is in the middle of handling clean up during object deletion.
 boolean isFloatLimited(arlut.csd.ganymede.DBField field)
          This method provides a hook that a DBEditObject subclass can use to indicate that a given FloatDBField has a restricted range of possibilities.
 boolean isIntLimited(arlut.csd.ganymede.DBField field)
          This method provides a hook that a DBEditObject subclass can use to indicate that a given NumericDBField has a restricted range of possibilities.
 boolean isIPv6OK(arlut.csd.ganymede.DBField field)
          This method provides a hook that a DBEditObject subclass can use to determine whether it is permissible to enter IPv6 address in a particular (IP) DBField.
 boolean isStored()
          Returns true if the object has ever been stored in the DBStore under the current invid.
 java.util.Date maxDate(arlut.csd.ganymede.DBField field)
          This method is used to specify the latest acceptable date for the specified DateDBField.
 double maxFloat(arlut.csd.ganymede.DBField field)
          This method is used to specify the maximum acceptable value for the specified FloatDBField.
 int maxInt(arlut.csd.ganymede.DBField field)
          This method is used to specify the maximum acceptable value for the specified NumericDBField.
 java.util.Date minDate(arlut.csd.ganymede.DBField field)
          This method is used to specify the earliest acceptable date for the specified DateDBField.
 double minFloat(arlut.csd.ganymede.DBField field)
          This method is used to specify the minimum acceptable value for the specified FloatDBField.
 int minInt(arlut.csd.ganymede.DBField field)
          This method is used to specify the minimum acceptable value for the specified NumericDBField.
 boolean mustChoose(arlut.csd.ganymede.DBField field)
          This method provides a hook that a DBEditObject subclass can use to indicate whether a given field can only choose from a choice provided by obtainChoiceList()
 arlut.csd.ganymede.QueryResult obtainChoiceList(arlut.csd.ganymede.DBField field)
          This method provides a hook that can be used to generate choice lists for invid and string fields that provide such.
 java.lang.Object obtainChoicesKey(arlut.csd.ganymede.DBField field)
          This method returns a key that can be used by the client to cache the value returned by choices().
 arlut.csd.ganymede.PermEntry permExpand(arlut.csd.ganymede.GanymedeSession session, arlut.csd.ganymede.DBObject object)
          Customization method to allow this Ganymede object type to grant permissions above and beyond the default permissions mechanism for special purposes.
 arlut.csd.ganymede.PermEntry permExpand(arlut.csd.ganymede.GanymedeSession session, arlut.csd.ganymede.DBObject object, short fieldid)
          Customization method to allow this Ganymede object type to grant permissions above and beyond the default permissions mechanism for special purposes.
 arlut.csd.ganymede.PermEntry permOverride(arlut.csd.ganymede.GanymedeSession session, arlut.csd.ganymede.DBObject object)
          Customization method to allow this Ganymede object type to override the default permissions mechanism for special purposes.
 arlut.csd.ganymede.PermEntry permOverride(arlut.csd.ganymede.GanymedeSession session, arlut.csd.ganymede.DBObject object, short fieldid)
          Customization method to allow this Ganymede object type to override the default permissions mechanism for special purposes.
 arlut.csd.ganymede.ReturnVal reactivate()
          This method handles reactivation logic for this object type.
 void release(boolean finalAbort)
          A hook for subclasses to use to clean up any external resources allocated for this object.
 arlut.csd.ganymede.ReturnVal remove()
          This method handles removal logic for this object type.
(package private)  void rollback(java.util.Hashtable ckpoint)
          Reinstates this object's state from a hashtable returned by checkpoint(), used by the DBEditSet intra-transaction checkpoint rollback logic to restore this object's state at a given time.
protected  void setCommitting(boolean state)
          This method is intended to be used by subclasses to set the state of this object's committing flag.
static void setDebug(boolean val)
           
 arlut.csd.ganymede.ReturnVal setFieldValue(short fieldID, java.lang.Object value)
          Shortcut method to set a field's value.
 arlut.csd.ganymede.ReturnVal setFieldValueLocal(short fieldID, java.lang.Object value)
          Shortcut method to set a field's value.
(package private)  void setStatus(byte new_status)
          Sets this object's status code
 boolean useLabelHook()
          This method should be defined to return true in DBEditObject subclasses which provide a getLabelHook() method.
 arlut.csd.ganymede.ReturnVal verifyNewValue(arlut.csd.ganymede.DBField field, java.lang.Object value)
          This method provides a hook that can be used to check any values to be set in any field in this object.
 boolean virtualizeField(short fieldID)
          This method provides a hook that can be used to indicate that a particular field's value should be filtered by a particular subclass of DBEditObject.
 arlut.csd.ganymede.ReturnVal wizardHook(arlut.csd.ganymede.DBField field, int operation, java.lang.Object param1, java.lang.Object param2)
          This method is the hook that DBEditObject subclasses use to interpose wizards when a field's value is being changed.
 
Methods inherited from class arlut.csd.ganymede.DBObject
canInactivate, checkRequiredFields, clearField, clearFieldPerm, clearShadow, createShadow, emit, emitXML, equals, exportFields, findField, getASymmetricTargets, getBackLinks, getBase, getContainingLabel, getEmailTargets, getExpirationDate, getField, getField, getFieldDef, getFieldId, getFieldInfoVector, getFieldName, getFieldPerm, getFieldValue, getFieldValueLocal, getFieldValues, getFieldValuesLocal, getFieldVect, getFieldVector, getGSession, getID, getInvid, getLabelField, getLabelFieldID, getPrintString, getRemovalDate, getSummaryDescription, getTypeDesc, getTypeID, getTypeName, hasEmailTarget, hashCode, isEmbedded, isInactivated, isSet, isValid, listFields, lookupLabel, print, print, receive, replaceField, retrieveField, saveField, setBackPointers, toString, unsetBackPointers, updateBaseRefs, willBeRemoved, willExpire
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

debug

static boolean debug

FIRSTOP

public static final int FIRSTOP
See Also:
Constant Field Values

SETVAL

public static final int SETVAL
See Also:
Constant Field Values

SETELEMENT

public static final int SETELEMENT
See Also:
Constant Field Values

ADDELEMENT

public static final int ADDELEMENT
See Also:
Constant Field Values

DELELEMENT

public static final int DELELEMENT
See Also:
Constant Field Values

ADDELEMENTS

public static final int ADDELEMENTS
See Also:
Constant Field Values

DELELEMENTS

public static final int DELELEMENTS
See Also:
Constant Field Values

SETPASSPLAIN

public static final int SETPASSPLAIN
See Also:
Constant Field Values

SETPASSCRYPT

public static final int SETPASSCRYPT
See Also:
Constant Field Values

SETPASSMD5

public static final int SETPASSMD5
See Also:
Constant Field Values

SETPASSWINHASHES

public static final int SETPASSWINHASHES
See Also:
Constant Field Values

SETPASSAPACHEMD5

public static final int SETPASSAPACHEMD5
See Also:
Constant Field Values

LASTOP

public static final int LASTOP
See Also:
Constant Field Values

minDate

public static final java.util.Date minDate

maxDate

public static final java.util.Date maxDate

original

protected arlut.csd.ganymede.DBObject original

Unless this DBEditObject was newly created, we'll have a reference to the original DBObject which is currently registered in the DBStore. Only one DBEditObject can be connected to a DBObject at a time, giving us object-level locking.


commitSemaphore

private arlut.csd.Util.booleanSemaphore commitSemaphore
true if this object has had its commitPhase1() method called, but has not yet had its commitPhase2() or release() methods called. If commitSemaphore is true, the DBField.isEditable() method will always return false for fields in this object, and no editing will be allowed on this object.


deleting

protected boolean deleting
true if the object is in the middle of carrying out deletion logic.. consulted by subclasses to determine whether they should object to fields being set to null


status

byte status
tracks this object's editing status. See ObjectStatus.


stored

boolean stored
true if the object has a version currently stored in the DBStore


editset

public arlut.csd.ganymede.DBEditSet editset
transaction that this object has been checked out in care of.

Constructor Detail

DBEditObject

public DBEditObject(arlut.csd.ganymede.DBObjectBase base)

Dummy constructor, is responsible for creating a DBEditObject strictly for the purpose of having a handle to call our pseudostatic customization methods on.

This is the version of the constructor that the DBObjectBase's createHook() method uses to create the objectHook object.


DBEditObject

public DBEditObject(arlut.csd.ganymede.DBObjectBase objectBase,
                    arlut.csd.ganymede.Invid invid,
                    arlut.csd.ganymede.DBEditSet editset)

Creation constructor, is responsible for creating a new editable object with all fields listed in the DBObjectBaseField instantiated but undefined.

This constructor is not really intended to be overriden in subclasses. Creation time field value initialization is to be handled by initializeNewObject().

See Also:
DBField

DBEditObject

public DBEditObject(arlut.csd.ganymede.DBObject original,
                    arlut.csd.ganymede.DBEditSet editset)

Check-out constructor, used by DBObject.createShadow() to pull out an object for editing.

Method Detail

setDebug

public static final void setDebug(boolean val)

getSession

public final arlut.csd.ganymede.DBSession getSession()

Returns the DBSession that this object is checked out in care of.

See Also:
DBSession

getEditSet

public final arlut.csd.ganymede.DBEditSet getEditSet()

Returns the transaction object owning this object, or null if an unowned data object.

Note that this is public, but not made available to the client via a remote interface.


getOriginal

public final arlut.csd.ganymede.DBObject getOriginal()

Returns the original version of the object that we were created to edit. If we are a newly created object, this method will return null.


getStatus

public final byte getStatus()

Returns a code indicating whether this object is being created, edited, or deleted.

See Also:
ObjectStatus.CREATING, ObjectStatus.EDITING, ObjectStatus.DELETING, ObjectStatus.DROPPING

isDeleting

public final boolean isDeleting()

This method returns true if this DBEditObject is in the middle of handling clean up during object deletion.


getLabel

public java.lang.String getLabel()

Returns the primary label of this object.. calls getLabelHook() on the DBEditObject serving as the objectHook for this object's DBObjectBase to get the label for this object.

If the objectHook customization object doesn't define a getLabelHook() method, this base implementation will return a string based on the designated label field for this object, or a generic label constructed based on the object type and invid if no label field is designated.

Specified by:
getLabel in interface db_object
Overrides:
getLabel in class DBObject
See Also:
db_object

checkNewField

public final boolean checkNewField(short fieldID)

This method is used to make sure that the built-in fields that the server assumes will always be present in any editable object will be in place.

This method checks with instantiateNewField() if the field id is not one of those that is needfull. If instantiateNewField() approves the creation of a new field, checkNewField() will check to see if the GanymedeSession's permissions permit the field creation.


setStatus

final void setStatus(byte new_status)

Sets this object's status code

See Also:
ObjectStatus.CREATING, ObjectStatus.EDITING, ObjectStatus.DELETING, ObjectStatus.DROPPING

setFieldValue

public final arlut.csd.ganymede.ReturnVal setFieldValue(short fieldID,
                                                        java.lang.Object value)

Shortcut method to set a field's value. Using this method can save the client a roundtrip to the server.

This method cannot be used on permission fields or password fields.

Specified by:
setFieldValue in interface db_object
Overrides:
setFieldValue in class DBObject
See Also:
db_object

setFieldValueLocal

public final arlut.csd.ganymede.ReturnVal setFieldValueLocal(short fieldID,
                                                             java.lang.Object value)

Shortcut method to set a field's value. This version bypasses permission checking and is only intended for server-side use.

This method cannot be used on permission fields or password fields.


isStored

public final boolean isStored()

Returns true if the object has ever been stored in the DBStore under the current invid.


anonymousLinkOK

public boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject,
                               short targetFieldID,
                               arlut.csd.ganymede.DBObject sourceObject,
                               short sourceFieldID,
                               arlut.csd.ganymede.GanymedeSession gsession)

This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

This version of anonymousLinkOK takes additional parameters to allow an object type to decide that it does or does not want to allow a link based on what field of what object wants to link to it.

By default, the 3 variants of the DBEditObject anonymousLinkOK() method are chained together, so that the customizer can choose which level of detail he is interested in. InvidDBField's bind() method calls this version. This version calls the three parameter version, which calls the two parameter version, which returns false by default. Customizers can implement any of the three versions, but unless you maintain the version chaining yourself, there's no point to implementing more than one of them.

Note that the choiceListHasExceptions() method will call this version of anonymousLinkOK() with a null targetObject, to determine that the client should not use its cache for an InvidDBField's choices. Any overriding done of this method must be able to handle a null targetObject, or else an exception will be thrown inappropriately.

The only reason to consult targetObject in any case is to allow or disallow anonymous object linking to a field based on the current state of the target object. If you are just writing generic anonymous linking rules for a field in this object type, targetObject won't concern you anyway. If you do care about the targetObject's state, though, you have to be prepared to handle a null valued targetObject.

*PSEUDOSTATIC*

Parameters:
targetObject - The object that the link is to be created in (may be null)
targetFieldID - The field that the link is to be created in
sourceObject - The object on the other side of the proposed link
sourceFieldID - The field on the other side of the proposed link
gsession - Who is trying to do this linking?

anonymousUnlinkOK

public boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject targetObject,
                                 short targetFieldID,
                                 arlut.csd.ganymede.DBObject sourceObject,
                                 short sourceFieldID,
                                 arlut.csd.ganymede.GanymedeSession gsession)

This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

This version of anonymousUnlinkOK takes additional parameters to allow an object type to decide that it does or does not want to allow a link to be rescinded based on what field of what object wants to unlink from it.

By default, the 3 variants of the DBEditObject anonymousUnlinkOK() method are chained together, so that the customizer can choose which level of detail he is interested in. InvidDBField's unbind() method calls this version. This version calls the three parameter version, which calls the two parameter version, which returns true by default. Customizers can implement any of the three versions, but unless you maintain the version chaining yourself, there's no point to implementing more than one of them.

*PSEUDOSTATIC*

Parameters:
targetObject - The object that the link is removed from
targetFieldID - The field that the link is removed from
sourceObject - The object on the other side of the existing link
sourceFieldID - The object on the other side of the existing link
gsession - Who is trying to do this unlinking?

anonymousLinkOK

public boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject,
                               short targetFieldID,
                               arlut.csd.ganymede.GanymedeSession gsession)

This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

See anonymousLinkOK(obj,short,obj,short,GanymedeSession) for details on anonymousLinkOK() method chaining.

Note that the choiceListHasExceptions() method will call this version of anonymousLinkOK() with a null targetObject, to determine that the client should not use its cache for an InvidDBField's choices. Any overriding done of this method must be able to handle a null targetObject, or else an exception will be thrown inappropriately.

The only reason to consult targetObject in any case is to allow or disallow anonymous object linking to a field based on the current state of the target object. If you are just writing generic anonymous linking rules for a field in this object type, targetObject won't concern you anyway. If you do care about the targetObject's state, though, you have to be prepared to handle a null valued targetObject.

*PSEUDOSTATIC*

Parameters:
targetObject - The object that the link is to be created in (may be null)
targetFieldID - The field that the link is to be created in
gsession - Who is trying to do this linking?

anonymousUnlinkOK

public boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject object,
                                 short fieldID,
                                 arlut.csd.ganymede.GanymedeSession gsession)

This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

By default, the server always allows anonymous unlinking. Overriding this method is only required when you want to DISallow such unlinking.

See anonymousUnlinkOK(obj,short,obj,short,GanymedeSession) for details on anonymousUnlinkOK() method chaining.

*PSEUDOSTATIC*

Parameters:
object - The object that the link is to be removed from
fieldID - The field that the linkk is to be removed from
gsession - Who is trying to do this unlinking?

anonymousLinkOK

public boolean anonymousLinkOK(arlut.csd.ganymede.DBObject targetObject,
                               short targetFieldID)

This method is used to control whether or not it is acceptable to make a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

See anonymousLinkOK(obj,short,obj,short,GanymedeSession) for details on anonymousLinkOK() method chaining.

Note that the choiceListHasExceptions() method will call this version of anonymousLinkOK() with a null targetObject, to determine that the client should not use its cache for an InvidDBField's choices. Any overriding done of this method must be able to handle a null targetObject, or else an exception will be thrown inappropriately.

The only reason to consult targetObject in any case is to allow or disallow anonymous object linking to a field based on the current state of the target object. If you are just writing generic anonymous linking rules for a field in this object type, targetObject won't concern you anyway. If you do care about the targetObject's state, though, you have to be prepared to handle a null valued targetObject.

*PSEUDOSTATIC*

Parameters:
targetObject - The object that the link is to be created in (may be null)
targetFieldID - The field that the link is to be created in

anonymousUnlinkOK

public boolean anonymousUnlinkOK(arlut.csd.ganymede.DBObject object,
                                 short fieldID)

This method is used to control whether or not it is acceptable to rescind a link to the given field in this DBObject type when the user only has editing access for the source InvidDBField and not the target.

By default, the server always allows anonymous unlinking. Overriding this method is only required when you want to DISallow such unlinking.

See anonymousUnlinkOK(obj,short,obj,short,GanymedeSession) for details on anonymousUnlinkOK() method chaining.

*PSEUDOSTATIC*

Parameters:
object - The object that the link is to be removed from
fieldID - The field that the linkk is to be removed from

permOverride

public arlut.csd.ganymede.PermEntry permOverride(arlut.csd.ganymede.GanymedeSession session,
                                                 arlut.csd.ganymede.DBObject object)

Customization method to allow this Ganymede object type to override the default permissions mechanism for special purposes.

If this method returns null, the default permissions mechanism will be followed. If not, the permissions system will grant the permissions specified by this method for access to the given object, and no further elaboration of the permission will be performed. Note that this override capability does not apply to operations performed in supergash mode.

Note as well that this permOverride() has no effect when creating new objects of this type. Take a look at overriding canCreate() if you need to provide an exception to the normal permissions system for creating new objects.

This method should be used very sparingly.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


permExpand

public arlut.csd.ganymede.PermEntry permExpand(arlut.csd.ganymede.GanymedeSession session,
                                               arlut.csd.ganymede.DBObject object)

Customization method to allow this Ganymede object type to grant permissions above and beyond the default permissions mechanism for special purposes.

If this method returns null, the default permissions mechanism will be followed. If not, the permissions system will grant the union of the permissions specified by this method for access to the given object.

Note as well that this permExpand() has no effect when creating new objects of this type. Take a look at overriding canCreate() if you need to provide an exception to the normal permissions system for creating new objects.

This method is essentially different from permOverride() in that the permissions system will not just take the result of this method for an answer, but will grant additional permissions as appropriate.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


permOverride

public arlut.csd.ganymede.PermEntry permOverride(arlut.csd.ganymede.GanymedeSession session,
                                                 arlut.csd.ganymede.DBObject object,
                                                 short fieldid)

Customization method to allow this Ganymede object type to override the default permissions mechanism for special purposes.

If this method returns null, the default permissions mechanism will be followed. If not, the permissions system will grant the permissions specified by this method for access to the given field, and no further elaboration of the permission will be performed. If permOverride() returns a non-null value for a given field, permExpand() will not be consulted for that field. Just as with permExpand(), this method can never cause greater permissions to be granted to a field than is available to the object as a whole, and this override capability does not apply to operations performed in supergash mode.

This method should be used very sparingly.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


permExpand

public arlut.csd.ganymede.PermEntry permExpand(arlut.csd.ganymede.GanymedeSession session,
                                               arlut.csd.ganymede.DBObject object,
                                               short fieldid)

Customization method to allow this Ganymede object type to grant permissions above and beyond the default permissions mechanism for special purposes.

If this method returns null, the default permissions mechanism will be followed. If not, the permissions system will grant the union of the permissions returned by this method and those determined normally by GanymedeSession's default field permissions logic. This method can never cause greater permissions to be granted to a field than is available to the object as a whole, and the results of permExpand() will have no effect on operations performed in supergash mode.

This method is essentially different from permOverride() in that the permissions system will not just take the result of this method for an answer, but will grant additional permissions as appropriate.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


consistencyCheck

public arlut.csd.ganymede.ReturnVal consistencyCheck(arlut.csd.ganymede.DBObject object)

Customization method to verify overall consistency of a DBObject. This method is intended to be overridden in DBEditObject subclasses, and will be called by commitPhase1() to verify the readiness of this object for commit. The DBObject passed to this method will be a DBEditObject, complete with that object's GanymedeSession reference if this method is called during transaction commit, and that session reference may be used by the verifying code if the code needs to access the database.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*

Returns:
A ReturnVal indicating success or failure. May be simply 'null' to indicate success if no feedback need be provided.

fieldRequired

public boolean fieldRequired(arlut.csd.ganymede.DBObject object,
                             short fieldid)

Customization method to control whether a specified field is required to be defined at commit time for a given object.

To be overridden in DBEditObject subclasses.

Note that this method will not be called if the controlling GanymedeSession's enableOversight is turned off, as in bulk loading.

*PSEUDOSTATIC*


canRead

public boolean canRead(arlut.csd.ganymede.DBSession session,
                       arlut.csd.ganymede.DBObject object)

Customization method to verify whether the user has permission to view a given object. The client's DBSession object will call this per-class method to do an object type- sensitive check to see if this object feels like being available for viewing to the client.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canSeeField

public boolean canSeeField(arlut.csd.ganymede.DBSession session,
                           arlut.csd.ganymede.DBField field)

Customization method to verify whether the user should be able to see a specific field in a given object. Instances of DBField will wind up calling up to here to let us override the normal visibility process.

Note that it is permissible for session to be null, in which case this method will always return the default visiblity for the field in question.

If field is not from an object of the same base as this DBEditObject, an exception will be thrown.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canWrite

public boolean canWrite(arlut.csd.ganymede.DBSession session,
                        arlut.csd.ganymede.DBObject object)

Customization method to verify whether the user has permission to edit a given object. The client's DBSession object will call this per-class method to do an object type- sensitive check to see if this object feels like being available for editing by the client.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canBeInactivated

public boolean canBeInactivated()

Customization method to verify whether this object type has an inactivation mechanism.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canInactivate

public boolean canInactivate(arlut.csd.ganymede.DBSession session,
                             arlut.csd.ganymede.DBEditObject object)

Customization method to verify whether the user has permission to inactivate a given object. The client's DBSession object will call this per-class method to do an object type- sensitive check to see if this object feels like being available for inactivating by the client.

Note that unlike canRemove(), canInactivate() takes a DBEditObject instead of a DBObject. This is because inactivating an object is based on editing the object, and so we have the GanymedeSession/DBSession classes go ahead and check the object out for editing before calling us. This serves to force the session classes to check for write permission before attempting inactivation.

Use canBeInactivated() to test for the presence of an inactivation protocol outside of an edit context if needed.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canRemove

public arlut.csd.ganymede.ReturnVal canRemove(arlut.csd.ganymede.DBSession session,
                                              arlut.csd.ganymede.DBObject object)

Customization method to verify whether the user has permission to remove a given object. The client's DBSession object will call this per-class method to do an object type- sensitive check to see if this object feels like being available for removal by the client.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canClone

public boolean canClone(arlut.csd.ganymede.DBSession session,
                        arlut.csd.ganymede.DBObject object)

Customization method to verify whether the user has permission to clone a given object. The client's DBSession object will call this per-class method to do an object type- sensitive check to see if this object feels like being available for cloning by the client.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canCloneField

public boolean canCloneField(arlut.csd.ganymede.DBSession session,
                             arlut.csd.ganymede.DBObject object,
                             arlut.csd.ganymede.DBField field)

Customization method to verify whether a specific field in object should be cloned using the basic field-clone logic.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


canCreate

public boolean canCreate(arlut.csd.ganymede.Session session)

Customization method to verify whether the user has permission to create an instance of this object type. The client's DBSession object will call the canCreate method in the DBObjectBase for this object type to determine whether creation is allowed to the user.

To be overridden in DBEditObject subclasses.

*PSEUDOSTATIC*


useLabelHook

public boolean useLabelHook()

This method should be defined to return true in DBEditObject subclasses which provide a getLabelHook() method.

If this method is not redefined to return true in any subclasses which define a getLabelHook() method, then searches on objects of this type may not properly reflect the desired label.

*PSEUDOSTATIC*


getLabelHook

public java.lang.String getLabelHook(arlut.csd.ganymede.DBObject object)

Hook to allow intelligent generation of labels for DBObjects of this type. Subclasses of DBEditObject should override this method to provide for custom generation of the object's label type

If you override this method to define a custom labelHook method for a DBEditObject subclass, you _must_ also override the useLabelHook() method to return true.

*PSEUDOSTATIC*


grantOwnership

public boolean grantOwnership(arlut.csd.ganymede.GanymedeSession gSession,
                              arlut.csd.ganymede.DBObject object)

Hook to allow subclasses to grant ownership privileges to a given object. If this method returns true on a given object, the Ganymede Permissions system will provide access to the object as owned with whatever permissions apply to objects owned by the persona active in gSession.

*PSEUDOSTATIC*


virtualizeField

public boolean virtualizeField(short fieldID)

This method provides a hook that can be used to indicate that a particular field's value should be filtered by a particular subclass of DBEditObject. This is intended to allow, for instance, that the Admin object's name field, if null, can have the owning user's name interposed.

24 June 1999 - note.. the whole virtualized field thing was put into DBEditObject a long long time ago, to support 'fields' whose reported value would not actually come from Ganymede's internal database. This code has in fact never been used, and is in its current state should probably not be depended on, as all the DBEditSet transaction commit / change logging stuff pays no attention to a virtualized field's value reporting.

*PSEUDOSTATIC*


getVirtualValue

public java.lang.Object getVirtualValue(arlut.csd.ganymede.DBField field)

This method provides a hook to return interposed values for fields that have their data massaged by a DBEditObject subclass.

24 June 1999 - note.. the whole virtualized field thing was put into DBEditObject a long long time ago, to support 'fields' whose reported value would not actually come from Ganymede's internal database. This code has in fact never been used, and is in its current state should probably not be depended on, as all the DBEditSet transaction commit / change logging stuff pays no attention to a virtualized field's value reporting.

*PSEUDOSTATIC*


hasEmailTarget

public boolean hasEmailTarget(arlut.csd.ganymede.DBObject object)

This method provides a hook to allow custom DBEditObject subclasses to indicate that the given object is interested in receiving notification when changes involving it occur, and can provide one or more addresses for such notification to go to.

*PSEUDOSTATIC*


getEmailTargets

public java.util.Vector getEmailTargets(arlut.csd.ganymede.DBObject object)

This method provides a hook to allow custom DBEditObject subclasses to return a Vector of Strings comprising a list of addresses to be notified above and beyond the normal owner group notification when the given object is changed in a transaction. Used for letting end-users be notified of changes to their account, etc.

If no email targets are present in this object, either a null value or an empty Vector may be returned.

*PSEUDOSTATIC*


initializeNewObject

public arlut.csd.ganymede.ReturnVal initializeNewObject()

Initializes a newly created DBEditObject.

When this method is called, the DBEditObject has been created, its ownership set, and all fields defined in the controlling DBObjectBase have been instantiated without defined values. If this DBEditObject is an embedded type, it will have been linked into its parent object before this method is called.

This method is responsible for filling in any default values that can be calculated from the DBSession associated with the editset defined in this DBEditObject.

If initialization fails for some reason, initializeNewObject() will return a ReturnVal with an error result.. If the owning GanymedeSession is not in bulk-loading mode (i.e., GanymedeSession.enableOversight is true), DBSession.createDBObject() will checkpoint the transaction before calling this method. If this method returns a failure code, the calling method will rollback the transaction. This method has no responsibility for undoing partial initialization, the checkpoint/rollback logic will take care of that.

If enableOversight is false, DBSession.createDBObject() will not checkpoint the transaction status prior to calling initializeNewObject(), so it is the responsibility of this method to handle any checkpointing needed.

This method should be overridden in subclasses.


instantiateNewField

public boolean instantiateNewField(short fieldID)

This method provides a hook that can be used to indicate whether a field that is defined in this object's field dictionary should be newly instantiated in this particular object.

This method does not affect those fields which are actually present in the object's record in the DBStore. What this method allows you to do is have a subclass decide whether it wants to instantiate a potential field (one that is declared in the field dictionary for this object, but which doesn't happen to be presently defined in this object) in this particular object.

A concrete example will help here. The Permissions Object type (base number SchemaConstants.PermBase) holds a permission matrix, a descriptive title, and a list of admin personae that hold those permissions for objects they own.

There are a few specific instances of SchemaConstants.PermBase that don't properly need the list of admin personae, as their object invids are hard-coded into the Ganymede security system, and their permission matrices are automatically consulted in certain situations. In order to support this, we're going to want to have a DBEditObject subclass for managing permission objects. In that subclass, we'll define instantiateNewField() so that it will return false if the fieldID corresponds to the admin personae list if the object's ID is that of one of these special objects. As a result, when the objects are viewed by an administrator, the admin personae list will not be seen.


cloneFromObject

public arlut.csd.ganymede.ReturnVal cloneFromObject(arlut.csd.ganymede.DBSession session,
                                                    arlut.csd.ganymede.DBObject origObj,
                                                    boolean local)

Hook to allow the cloning of an object. If this object type supports cloning (which should be very much customized for this object type.. creation of the ancillary objects, which fields to clone, etc.), this customization method will actually do the work.

This method is called on a newly created object, in order to clone the state of origObj into it. This method does not actually create a new object.. that is handled by arlut.csd.ganymede.GanymedeSession#clone_db_object(arlut.csd.ganymede.Invid) before this method is called on the newly created object.

The default (DBEditObject) implementation of this method will only clone fields for which {@link arlut.csd.ganymede.DBEditObject#canCloneField(arlut.csd.ganymede.DBSession, arlut.csd.ganymede.DBObject, arlut.csd.ganymede.DBField) canCloneField()} returns true, and which are not connected to a namespace (and thus could not possibly be cloned).

If one or more fields in the original object are unreadable by the cloning session, we will provide a list of fields that could not be cloned due to a lack of read permissions in a dialog in the ReturnVal. Such a problem will not result in a failure code being returned, however.. the clone will succeed, but an informative dialog will be provided to the user.

Parameters:
session - The DBSession that the new object is to be created in
origObj - The object we are cloning
local - If true, fields that have choice lists will not be checked against those choice lists and read permissions for each field will not be consulted. The canCloneField() method will still be consulted, however.
Returns:
A standard ReturnVal status object. May be null on success, or else may carry a dialog with information on problems and a success flag.

wizardHook

public arlut.csd.ganymede.ReturnVal wizardHook(arlut.csd.ganymede.DBField field,
                                               int operation,
                                               java.lang.Object param1,
                                               java.lang.Object param2)

This method is the hook that DBEditObject subclasses use to interpose wizards when a field's value is being changed.

Whenever a field is changed in this object, this method will be called with details about the change. This method can refuse to perform the operation, it can make changes to other objects in the database in response to the requested operation, or it can choose to allow the operation to continue as requested.

In the latter two cases, the wizardHook code may specify a list of fields and/or objects that the client may need to update in order to maintain a consistent view of the database.

If server-local code has called enableOversight(false), this method will never be called. This mode of operation is intended only for initial bulk-loading of the database.

This method may also be bypassed when server-side code uses setValueLocal() and the like to make changes in the database.

This method is called