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 before the finalize*() methods.. the finalize*() methods is where last minute cascading changes should be performed.. Note as well that wizardHook() is called before the namespace checking for the proposed value is performed, while the finalize*() methods are called after the namespace checking.

The operation parameter will be a small integer, and should hold one of the following values:

1 - SETVAL
This operation is used whenever a simple scalar field is having it's value set. param1 will be the value being placed into the field.
2 - SETELEMENT
This operation is used whenever a value in a vector field is being set. param1 will be an Integer holding the element index, and param2 will be the value being set.
3 - ADDELEMENT
This operation is used whenever a value is being added to the end of a vector field. param1 will be the value being added.
4 - DELELEMENT
This operation is used whenever a value in a vector field is being deleted. param1 will be an Integer holding the element index.
5 - ADDELEMENTS
This operation is used whenever a set of elements is being added to a vector field en masse. param1 will be a Vector containing the values that are being added.
6 - DELELEMENTS
This operation is used whenever a set of elements is being deleted from a vector field en masse. param1 will be a Vector containing the values that are being deleted.
7 - SETPASSPLAIN
This operation is used when a password field is having its password set using a plaintext source. param1 will be a String containing the submitted password, or null if the password is being cleared.
8 - SETPASSCRYPT
This operation is used when a password field is having its password set using a UNIX crypt() hashed source. param1 will be a String containing the submitted hashed password, or null if the password is being cleared.
9 - SETPASSMD5
This operation is used when a password field is having its password set using an md5Ccrypt() hashed source. param1 will be a String containing the submitted hashed password, or null if the password is being cleared.
10 - SETPASSWINHASHES
This operation is used when a password field is having its password set using Windows style password hashes. param1 will be the password in LANMAN hash form, param2 will be the password in NT Unicode MD4 hash form. Either or both of param1 and param2 may be null.

Returns:
a ReturnVal object indicated success or failure, objects and fields to be rescanned by the client, and a doNormalProcessing flag that will indicate to the field code whether or not the operation should continue to completion using the field's standard logic. It is very important that wizardHook return a new ReturnVal(true, true) if the wizardHook wishes to simply specify rescan information while having the field perform its standard operation. wizardHook() may return new ReturnVal(true, false) if the wizardHook performs the operation (or a logically related operation) itself. The same holds true for the respond() method in GanymediatorWizard subclasses.

createNewEmbeddedObject

public arlut.csd.ganymede.ReturnVal createNewEmbeddedObject(arlut.csd.ganymede.InvidDBField field)

Hook to have this object create a new embedded object in the given field.

This method now has the appropriate default logic for creating embedded objects with the user's permissions, but this method may still be overridden to do customization, if needed.


verifyNewValue

public 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. Subclasses of DBEditObject should override this method, implementing basically a large switch statement to check for any given field whether the submitted value is acceptable given the current state of the object.

Question: what synchronization issues are going to be needed between DBEditObject and DBField to insure that we can have a reliable verifyNewValue method here?


finalizeDeleteElement

public 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.. if this method returns null or a success code in its ReturnVal, the DBField that called us is guaranteed to proceed to make the change to its vector. If this method returns a non-success code in its ReturnVal, the DBField that called us will not make the change, and the field will be left unchanged.

The <field> parameter identifies the field that is requesting approval for item deletion, and the <index> parameter identifies the element number that is to be deleted.

The DBField that called us will take care of all standard checks on the operation (including vector bounds, etc.) before calling this method. Under normal circumstances, we won't need to do anything here.


finalizeDeleteElements

public 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.. if this method returns null or a success code in its ReturnVal, the DBField that called us is guaranteed to proceed to make the change to its vector. If this method returns a non-success code in its ReturnVal, the DBField that called us will not make the change, and the field will be left unchanged.

The <field> parameter identifies the field that is requesting approval for item deletion, and the <valuesToDelete> parameter contains a list of elements to be deleted.

The DBField that called us will take care of all standard checks on the operation (including vector bounds, etc.) before calling this method. Under standard circumstances, we won't need to do anything here.


finalizeAddElement

public 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.. if this method returns null or a success code in its ReturnVal, the DBField that called us is guaranteed to proceed to make the change to its vector. If this method returns a non-success code in its ReturnVal, the DBField that called us will not make the change, and the field will be left unchanged.

The <field> parameter identifies the field that is requesting approval for item deletion, and the <value> parameter carries the value to be added.

The DBField that called us will take care of all standard checks on the operation (including vector bounds, etc.) before calling this method. Under normal circumstances, we won't need to do anything here.


finalizeAddElements

public 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.. if this method returns null or a success code in its ReturnVal, the DBField that called us is guaranteed to proceed to make the change to its vector. If this method returns a non-success code in its ReturnVal, the DBField that called us will not make the change, and the field will be left unchanged.

The <field> parameter identifies the field that is requesting approval for item deletion, and the <submittedValues> parameter carries the values to be added.

The DBField that called us will take care of all standard checks on the operation (including vector bounds, etc.) before calling this method. Under normal circumstances, we won't need to do anything here.


finalizeSetElement

public 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.. if this method returns null or a success code in its ReturnVal, the DBField that called us is guaranteed to proceed to make the change to its vector. If this method returns a non-success code in its ReturnVal, the DBField that called us will not make the change, and the field will be left unchanged.

The <field> parameter identifies the field that is requesting approval for item deletion, the <index> parameter identifies which element in the given vector field is to be set, and the <value> parameter carries the proposed new value.

The DBField that called us will take care of all standard checks on the operation (including vector bounds, etc.) before calling this method. Under normal circumstances, we won't need to do anything here.


finalizeSetValue

public 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. When a scalar field has its value set, it will call its owners finalizeSetValue() method, passing itself as the <field> parameter, and passing the new value to be approved as the <value> parameter. A Ganymede customizer who creates custom subclasses of the DBEditObject class can override the finalizeSetValue() method and write his own logic to examine any change and either approve or reject the change.

A custom finalizeSetValue() method will typically need to examine the field parameter to see which field is being changed, and then do the appropriate checking based on the value parameter. The finalizeSetValue() method can call the normal this.getFieldValueLocal() type calls to examine the current state of the object, if such information is necessary to make appropriate decisions.

If finalizeSetValue() returns null or a ReturnVal object with a positive success value, the DBField that called us is guaranteed to proceed to make the change to its value. If this method returns a non-success code in its ReturnVal, as with the result of a call to Ganymede.createErrorDialog(), the DBField that called us will not make the change, and the field will be left unchanged. Any error dialog returned from finalizeSetValue() will be passed to the user.

The DBField that called us will take care of all standard checks on the operation (including a call to our own verifyNewValue() method before calling this method. Under normal circumstances, we won't need to do anything here. finalizeSetValue() is useful when you need to do unusually involved checks, and for when you want a chance to trigger other changes in response to a particular field's value being changed.


excludeSelected

public 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.

The purpose of this method is to allow mutual exclusion between a pair of fields with mandatory choices.

To be overridden in DBEditObject subclasses.


obtainChoicesKey

public 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(). If the client already has the key cached on the client side, it can provide the choice list from its cache rather than calling choices() on this object again.

If there is no caching key, this method will return null.


obtainChoiceList

public 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. String and Invid DBFields will call their owner's obtainChoiceList() method to get a list of valid choices.

This method will provide a reasonable default for targetted invid fields, filtered by the GanymedeSession's visibilityFilterInvids list.

NOTE: This method does not need to be synchronized. Making this synchronized can lead to DBEditObject/DBSession nested monitor deadlocks.


choiceListHasExceptions

public 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. If this method returns true, that means that some of the results that obtainChoiceList() will return will include items that normally wouldn't be availble to the client, but are in this case because of the anonymousLinkOK() results.

This is kind of wacked-out random stuff. It's basically a way of allowing DBEditObject to get involved in the decision as to whether an InvidDBField's choicesKey()'s method should disallow client-side caching for the field's choice list.


mustChoose

public 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()


isIPv6OK

public 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.


isDateLimited

public 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.


minDate

public java.util.Date minDate(arlut.csd.ganymede.DBField field)
This method is used to specify the earliest acceptable date for the specified DateDBField.


maxDate

public java.util.Date maxDate(arlut.csd.ganymede.DBField field)
This method is used to specify the latest acceptable date for the specified DateDBField.


isIntLimited

public 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.


minInt

public int minInt(arlut.csd.ganymede.DBField field)
This method is used to specify the minimum acceptable value for the specified NumericDBField.


maxInt

public int maxInt(arlut.csd.ganymede.DBField field)
This method is used to specify the maximum acceptable value for the specified NumericDBField.


isFloatLimited

public 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.


minFloat

public double minFloat(arlut.csd.ganymede.DBField field)
This method is used to specify the minimum acceptable value for the specified FloatDBField.


maxFloat

public double maxFloat(arlut.csd.ganymede.DBField field)
This method is used to specify the maximum acceptable value for the specified FloatDBField.


inactivate

public arlut.csd.ganymede.ReturnVal inactivate()

This method handles inactivation logic for this object type. A DBEditObject must first be checked out for editing, then the inactivate() method can then be called on the object to put the object into inactive mode. inactivate() will set the object's removal date and fix up any other state information to reflect the object's inactive status.

inactive() is designed to run synchronously with the user's request for inactivation. It can return a wizard reference in the ReturnVal object returned, to guide the user through a set of interactive dialogs to inactive the object.

The inactive() method can cause other objects to be deleted, can cause strings to be removed from fields in other objects, whatever.

If inactivate() returns a ReturnVal that has its success flag set to false and does not include a JDialogBuff for further interaction with the user, then DBSEssion.inactivateDBObject() method will rollback any changes made by this method.

If inactivate() returns a success value, we expect that the object will have a removal date set.

IMPORTANT NOTE 1: This method is intended to be called by the DBSession.inactivateDBObject() method, which establishes a checkpoint before calling inactivate. If this method is not called by DBSession.inactivateDBObject(), you need to push a checkpoint with the key 'inactivate'+label, where label is the returned name of this object.

IMPORTANT NOTE 2: If a custom object's inactivate() logic decides to enter into a wizard interaction with the user, that logic is responsible for calling finalizeInactivate() with a boolean indicating ultimate success of the operation.

Finally, it is up to commitPhase1() and commitPhase2() to handle any external actions related to object inactivation when the transaction is committed..

See Also:
commitPhase1(), commitPhase2()

finalizeInactivate

public final 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.

If inactivation of an object causes the label to be null, this won't work as well as we'd really like.


reactivate

public arlut.csd.ganymede.ReturnVal reactivate()

This method handles reactivation logic for this object type. A DBEditObject must first be checked out for editing, then the reactivate() method can then be called on the object to make the object active again. reactivate() will clear the object's removal date and fix up any other state information to reflect the object's reactive status.

reactive() is designed to run synchronously with the user's request for inactivation. It can return a wizard reference in the ReturnVal object returned, to guide the user through a set of interactive dialogs to reactive the object.

If reactivate() returns a ReturnVal that has its success flag set to false and does not include a JDialogBuff for further interaction with the user, then inactivateDBObject() method will rollback any changes made by this method.

IMPORTANT NOTE: If a custom object's inactivate() logic decides to enter into a wizard interaction with the user, that logic is responsible for calling finalizeInactivate() with a boolean indicating ultimate success of the operation.

Finally, it is up to commitPhase1() and commitPhase2() to handle any external actions related to object reactivation when the transaction is committed..

See Also:
commitPhase1(), commitPhase2()

finalizeReactivate

protected final 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.


remove

public arlut.csd.ganymede.ReturnVal remove()

This method handles removal logic for this object type. This method will be called immediately from DBSession.deleteDBObject().

The remove() method can cause other objects to be deleted, can cause strings to be removed from fields in other objects, whatever.

If remove() returns a ReturnVal that has its success flag set to false and does not include a JDialogBuff for further interaction with the user, the DBSession.deleteDBObject() method will roll back any changes made by this method.

remove() is intended for subclassing, whereas finalizeRemove() is not. finalizeRemove() provides the standard logic for wiping out fields and what not to cause the object to be unlinked from other objects.

IMPORTANT NOTE: If a custom object's remove() logic decides to enter into a wizard interaction with the user, that logic is responsible for calling finalizeRemove() on the object when it is determined that the object really should be removed, with a boolean indicating whether success was had.


finalizeRemove

public final arlut.csd.ganymede.ReturnVal finalizeRemove(boolean success)

This method handles Ganymede-internal deletion logic for this object type. finalizeRemove() is responsible for dissolving any invid inter-object references in particular.

It is up to commitPhase1() and commitPhase2() to handle any external actions related to object removal when the transaction is committed..

finalizeremove() returns a ReturnVal indicating whether the internal removal bookkeeping was successful. A failure result will cause the DBSession to rollback the transaction to the state prior to any removal actions for this object were attempted.

remove() is intended for subclassing, whereas finalizeRemove() is not. finalizeRemove() provides the standard logic for wiping out fields and what not to cause the object to be unlinked from other objects.

Parameters:
success - If true, finalizeRemove() will clear all fields, thereby unlinking invid fields and relinquishing namespace claims. If false, finalizeRemove() will rollback to the state the system was in before DBSession.deleteDBObject() was entered.
See Also:
commitPhase1(), commitPhase2()

attemptBackLinkClear

private final 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. We do this by consulting the global Ganymede.db.backPointers hash structure to get the list of objects which point to us, and doing the unlink in a fashion similar to InvidDBField.unbindAll().

This method is private, and is not to be called by any code outside of this class.

Parameters:
local - if true, this operation will be performed without regard to permissions limitations.
Returns:
null on success, or a ReturnVal with an error dialog encoded on failure

clearBackLink

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.

This method does no checkpointing, so attemptBackLinkClear() has to do that for us.

Parameters:
remote - An Invid for an object that we have asymmetric back links to.
local - If true, we won't do a permissions check before trying to edit the remote object.

commitPhase1

public arlut.csd.ganymede.ReturnVal commitPhase1()

This method performs verification for the first phase of the two-phase commit algorithm. If this object returns true from commitPhase1() when called during an editSet's commit() routine, this object CAN NOT refuse commit() at a subsequent point. Once commitPhase1() is called, the object CAN NOT be changed until the transaction is either committed, abandoned, or released from the commit process by the release() method.

This method is intended to be subclassed by application objects that need to include extra-Ganymede processes in the two-phase commit protocol. If a particular subclass of DBEditObject does not need to involve outside processes in the full two-phase commit protocol, this method should not be overridden.

If this method is overridden, be sure and call setCommitting(true) before doing anything else. Failure to call setCommitting() in this method will cause the two phase commit mechanism to behave unpredictably.

WARNING! this method is called at a time when portions of the database are locked for the transaction's integration into the database. You must not call methods that seek to gain a lock on the Ganymede database. At this point, this means no composite queries on embedded object types, where you seek an object based on a field in an embedded object and in the object itself, using the GanymedeSession query calls, or else you will lock the server.

This method should NEVER try to edit or change any DBEditObject in the server.. at this point in the game, the server has fixed the transaction working set and is depending on commitPhase1() not trying to make changes.

See Also:
DBEditSet

isCommitting

public final 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.

DBField's isEditable() method consults this method to determine whether to allow editing of fields. While a DBEditObject is in the committing process, no changes to fields will be allowed.


setCommitting

protected final void setCommitting(boolean state)

This method is intended to be used by subclasses to set the state of this object's committing flag.


commitPhase2

public void commitPhase2()

This method is a hook for subclasses to override to pass the phase-two commit command to external processes.

For normal usage this method would not be overridden. For cases in which change to an object would result in an external process being initiated whose success or failure would not affect the successful commit of this DBEditObject in the Ganymede server, the process invocation should be placed here, rather than in commitPhase1().

commitPhase2() is generally the last method called on a DBEditObject before it is discarded by the server in the DBEditSet commit() method.

Subclasses that override this method may wish to make this method synchronized.

WARNING! this method is called at a time when portions of the database are locked for the transaction's integration into the database. You must not call methods that seek to gain a lock on the Ganymede database. At this point, this means no composite queries on embedded object types, where you seek an object based on a field in an embedded object and in the object itself, using the GanymedeSession query calls, or else you will lock the server.

This method should NEVER try to edit or change any DBEditObject in the server.. at this point in the game, the server has fixed the transaction working set and is depending on commitPhase2() not trying to make changes internal to the server.


release

public void release(boolean finalAbort)

A hook for subclasses to use to clean up any external resources allocated for this object. This method can be called after commitPhase1() has been called, or it may be called at any time to indicate that this object is being withdrawn from the transaction (as by a checkpoint rollback). This method will not be called after commitPhase2() has been called. If you do anything external in commitPhase2(), make sure that all resources allocated for this object (at any time in this object's editing life-cycle) are released before commitPhase2() completes.

Ordinarily, there is no need for customizers to override this method. The only reason to override the release method is if you need to do maintenance on external data structures or connections that were created in commitPhase1() or when this DBEditObject was created.

If <finalAbort> is true, the transaction for which this DBEditObject was created is being completely abandoned (if isCommitting() returns true), or this object is being dropped out of the transaction by a checkpoint rollback. In either case, a customizer may want to clean up all external structures or connections that were created either at the time this DBEditObject was created/checked-out and/or that were created by commitPhase1().

If <finalAbort> is false, isCommitting() should always return true. In this case, one of the DBEditObjects in the transaction returned false from a later commitPhase1() call and all objects that had their commitPhase1() methods called previously will be revisted and release(false) will be called on them. Customizers may want to clean up any external structures or connections that were established in commitPhase1().

Remember, you will usually want to perform external actions in commitPhase2(), in which case release() is not needed. release() is only useful when you allocate external structures or connections when the object is created or during commitPhase1().

It is safe to call release() from your commitPhase2() method if you wish to have one place to clean up structures allocated by initializeNewObject() or commitPhase1().

Customizers subclassing this method may want to keep a couple of things in mind. First, the default release method is not synchronized, and it basically just clear a boolean flag (call setCommitting(false)) to indicate that edit methods on this object may once again go forward. You may want to synchronize your release method if you do anything at all fancy. More importantly, it is essential that you call setCommitting(false) if <finalAbort> is false so that this object can be edited afterwards.

WARNING! this method is called at a time when portions of the database are locked for the transaction's integration into the database. You must not call methods that seek to gain a lock on the Ganymede database. At this point, this means no composite queries on embedded object types, where you seek an object based on a field in an embedded object and in the object itself, using the GanymedeSession query calls, or else you will lock the server.

Parameters:
finalAbort - If true, this object is being dropped, either due to an aborted transaction or a checkpoint rollback.

checkpoint

final 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.

Each subclass of DBField is responsible for implementing its own version of checkpoint() to stuff its state into an Object for inclusion in this method's hashtable.


rollback

final 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.

Each subclass of DBField is responsible for implementing its own version of rollback() to restore its state.


diff

public 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.

This method can also be used if this object is newly created.. in this case, it will just return a string containing many 'FieldAdded' entries.

Returns:
null if no difference was found

internalSession

protected final 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.