FileDocCategorySizeDatePackage
UpdateObjectDescImpl.javaAPI DocGlassfish v2 API16717Fri May 04 22:35:12 BST 2007com.sun.jdo.spi.persistence.support.sqlstore.sql

UpdateObjectDescImpl

public class UpdateObjectDescImpl extends Object implements UpdateObjectDesc
Stores the update information for the associated state manager.

Fields Summary
private List
afterHiddenValues
Array of Object.
private SQLStateManager
afterImage
private List
beforeHiddenValues
Array of Object.
private SQLStateManager
beforeImage
private com.sun.jdo.spi.persistence.support.sqlstore.sql.concurrency.Concurrency
concurrency
private Class
pcClass
private int
updateAction
private List
updatedFields
Array of LocalFieldDesc. Fields contained in this array are written to the database.
private Map
updatedJoinTableRelationships
private boolean
relationshipChanged
Marker for fast relationship update check.
private static com.sun.jdo.spi.persistence.utility.logging.Logger
logger
The logger.
private static final ResourceBundle
messages
I18N message handler.
Constructors Summary
public UpdateObjectDescImpl(Class pcClass)


       
		this.pcClass = pcClass;
        updatedFields = new ArrayList();
    
Methods Summary
public voidclearUpdatedJoinTableRelationships()

        updatedJoinTableRelationships = null;
    
public SQLStateManagergetAfterImage()

        return afterImage;
    
public java.lang.ObjectgetAfterValue(com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc f)

        if (afterImage == null) {
            throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
                "sqlstore.sql.updateobjdescimpl.afterimagenull")); //NOI18N
        }

        if (f.absoluteID < 0) {
            return afterHiddenValues.get(-(f.absoluteID + 1));
        } else {
            return f.getValue(afterImage);
        }
    
public java.lang.ObjectgetBeforeValue(com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc f)

        if (beforeImage == null) {
            throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
                "sqlstore.sql.updateobjdescimpl.beforeimagenull")); //NOI18N
        }

        if (f.absoluteID < 0) {
            return beforeHiddenValues.get(-(f.absoluteID + 1));
        } else {
            return f.getValue(beforeImage);
        }
    
public com.sun.jdo.spi.persistence.support.sqlstore.sql.concurrency.ConcurrencygetConcurrency()

        return concurrency;
    
public com.sun.jdo.spi.persistence.support.sqlstore.model.ClassDescgetConfig()

        return (ClassDesc) afterImage.getPersistenceConfig();
    
public java.lang.ClassgetPersistenceCapableClass()

        return pcClass;
    
public intgetUpdateAction()

        return updateAction;
    
public java.util.CollectiongetUpdateJoinTableDescs(com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc fieldDesc)

        HashMap updateJoinTableDescs = (HashMap) updatedJoinTableRelationships.get(fieldDesc);

        if (updateJoinTableDescs != null) {
            return updateJoinTableDescs.values();
        }

        return null;
    
public java.util.ListgetUpdatedFields()

        return updatedFields;
    
public java.util.CollectiongetUpdatedJoinTableFields()

        if (updatedJoinTableRelationships == null) {
            return null;
        }

        return updatedJoinTableRelationships.keySet();
    
public booleanhasChangedRelationships()
Returns true, if this state manager has a changed relationship field.

return
True, if this state manager has a changed relationship field.

        // If the relationship is set before the makePersistent call,
        // this condition might be false for INSERTs.
        if (relationshipChanged) {
            return true;
        }

        // Check for updated join table relationships.
        if (hasUpdatedJoinTableRelationships()) {
            return true;
        }

        // Check for updated foreign key relationships.
        if (updatedFields != null) {
            for (Iterator iter = updatedFields.iterator(); iter.hasNext(); ) {
                LocalFieldDesc field = (LocalFieldDesc) iter.next();
                if (field.isForeignKeyField()) {
                    return true;
                }
            }
        }

        return false;
    
public booleanhasModifiedLobField()
Returns true if any of the changed fields is byte[].


        if (updatedFields != null) {
            for (Iterator i = updatedFields.iterator(); i.hasNext(); ) {

                // The list updatedFields only contains LocalFieldDesc.
                // Thus it's safe to cast to LocalFieldDesc below.
                LocalFieldDesc field = (LocalFieldDesc)i.next();
                if (field.isMappedToLob()) {
                    return true;
                }
            }
        }

        return false;
    
public booleanhasUpdatedFields()

        return (updatedFields.size() > 0);
    
public booleanhasUpdatedJoinTableRelationships()

        return (updatedJoinTableRelationships != null &&
                updatedJoinTableRelationships.size() > 0);
    
public booleanhasVersionConsistency()

        return afterImage.hasVersionConsistency();
    
public voidincrementVersion()
Triggers the version update if the associated state manager is registered for version consistency and database fields have been modified. The version is incremented, if
  • The associated instance is version consistent.
  • The associated instance has updated database fields.
Note: The version is not incremented, if a relationship mapped to a join table was updated.


        if (afterImage.hasVersionConsistency()
                && updateAction == ActionDesc.LOG_UPDATE
                && hasUpdatedFields()) {

            afterImage.incrementVersion();
        }
    
public booleanisBeforeImageRequired()

        return afterImage.isBeforeImageRequired();
    
public voidmarkRelationshipChange(com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc fieldDesc)
Marks the relationship change property for this instance, if the updated field is a relationship field or a hidden field tracing a foreign key column in the database.

param
fieldDesc Updated field.

        if (fieldDesc.isRelationshipField() || fieldDesc.isForeignKeyField()) {
            if (logger.isLoggable(Logger.FINEST)) {
                logger.finest("sqlstore.sql.updateobjdescimpl.markrelationshipchange"); // NOI18N
            }
            // MARK THE RELATIONSHIP CHANGE for this instance.
            relationshipChanged = true;
        }
    
public voidrecordUpdatedField(com.sun.jdo.spi.persistence.support.sqlstore.model.LocalFieldDesc fieldDesc)

        if (!updatedFields.contains(fieldDesc))
            updatedFields.add(fieldDesc);
    
public voidrecordUpdatedJoinTableRelationship(com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc fieldDesc, SQLStateManager parentSM, SQLStateManager foreignSM, int action)
Schedules a jointable entry for relationship field fieldDesc. The scheduled jointable entry is uniquely identified by the relationship field and the two associated state managers. The action parameter specifies, if the jointable entry should be created or removed.

param
fieldDesc Updated relationship field.
param
parentSM State manager responsible for fieldDesc's defining class.
param
foreignSM State manager responsible for the other side.
param
action The action is either CREATE or REMOVE.
see
#removeUpdatedJoinTableRelationship

        if (updatedJoinTableRelationships == null) {
            updatedJoinTableRelationships = new HashMap();
        }

        HashMap updateJoinTableDescs = null;

        if ((updateJoinTableDescs = (HashMap) updatedJoinTableRelationships.get(fieldDesc)) == null) {
            updateJoinTableDescs = new HashMap();
            updatedJoinTableRelationships.put(fieldDesc, updateJoinTableDescs);
        }

        UpdateJoinTableDesc desc = null;

        if ((desc = (UpdateJoinTableDesc) updateJoinTableDescs.get(foreignSM)) == null) {
            desc = new UpdateJoinTableDesc(parentSM, foreignSM, action);
            updateJoinTableDescs.put(foreignSM, desc);
        }
    
public booleanremoveUpdatedJoinTableRelationship(com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc fieldDesc, SQLStateManager foreignSM, int action)
Removes a previously scheduled jointable entry for relationship field fieldDesc. The action parameter specifies, if the entry to be removed is scheduled for creation or removal.

param
fieldDesc Updated relationship field.
param
foreignSM Associated state manager on the opposite side.
param
action The action is either CREATE or REMOVE.
return
True, if the specified jointable entry was found and removed, false otherwise.
see
#recordUpdatedJoinTableRelationship

        HashMap updateJoinTableDescs = null;

        if ((updatedJoinTableRelationships == null) ||
                ((updateJoinTableDescs = (HashMap) updatedJoinTableRelationships.get(fieldDesc)) == null)) {
            return false;
        }

        UpdateJoinTableDesc desc = (UpdateJoinTableDesc) updateJoinTableDescs.get(foreignSM);
        if (desc != null && desc.getAction() == action) {
            return (updateJoinTableDescs.remove(foreignSM) != null);
        }

        return false;
    
public voidreset()

        updatedFields.clear();

        if (updatedJoinTableRelationships != null) {
            updatedJoinTableRelationships.clear();
        }

        relationshipChanged = false;
        concurrency = null;
    
public voidsetConcurrency(com.sun.jdo.spi.persistence.support.sqlstore.sql.concurrency.Concurrency concurrency)

        this.concurrency = concurrency;
    
public voidsetObjectInfo(StateManager biStateManager, StateManager aiStateManager, int action)
We send the AfterImage for updates and inserts but for updates it will only hold values for updated attributes (unless the class is configured to send the whole AfterImage, also we'll let the concurrency interface affect the sent AfterImage (and the sent BeforeImage)). For deletes the AfterImage will be NIL, for inserts the BeforeImage will be NIL. For deletes the BeforeImage will contain values for all key attributes. Also for deletes and updates we'll send the HiddenValues array from the paladin (although we can set to NIL any values in the array not needed by this particular update). UpdatedAttributes will contain indexes into the PersistentDesc.Attributes array for new or updated values. Initially we'll probably just send the whole BeforeImage and AfterImage (except that we won't have an AfterImage for Deletes and we won't have a BeforeImage for updates).


        this.beforeImage = (SQLStateManager) biStateManager;
        this.afterImage = (SQLStateManager) aiStateManager;
        ClassDesc config = (ClassDesc) afterImage.getPersistenceConfig();
        updateAction = action;

        this.afterHiddenValues = afterImage.hiddenValues;

        if (beforeImage != null) {
            this.beforeHiddenValues = beforeImage.hiddenValues;
        }

        // This pass through attributes we are only going to look at local attributes.
        // These are attributes that are stored in this object and are not references
        // to other persistent objects.

        boolean debug = logger.isLoggable(Logger.FINER);

        for (int i = 0; i < config.fields.size(); i++) {
            FieldDesc f = (FieldDesc) config.fields.get(i);
            LocalFieldDesc lf = null;
            boolean updated = false;

            if (f instanceof LocalFieldDesc) {
                lf = (LocalFieldDesc) f;
            } else {
                continue;
            }

            if ((updateAction == LOG_DESTROY) ||
                    ((lf.sqlProperties & FieldDesc.PROP_RECORD_ON_UPDATE) > 0)) {
                continue;
            } else if (lf.absoluteID < 0) {
                if ((beforeImage == null) ||
                        (beforeImage.getHiddenValue(lf.absoluteID) !=
                        afterImage.getHiddenValue(lf.absoluteID))) {
                    updated = true;
                }
            } else if (lf.getType().isPrimitive() ||
                    String.class == lf.getType() ||
                    java.util.Date.class == lf.getType()) {
                Object afterVal = lf.getValue(afterImage);
                Object beforeVal = null;

                if (beforeImage != null) {
                    beforeVal = lf.getValue(beforeImage);
                }

                if ((beforeVal != null) && (afterVal != null)) {
                    if (!beforeVal.equals(afterVal)) {
                        updated = true;
                    }
                } else {
                    updated = true;
                }
            } else {
                // What else??
            }

            if (updated) {
                if (debug) {
                    logger.finer("sqlstore.sql.updateobjdescimpl.updated", f.getName()); // NOI18N
                }

                updatedFields.add(lf);
            }
        }

        if (concurrency != null) {
            concurrency.commit(this, beforeImage, afterImage, updateAction);
        }
    
public voidsetVerificationFailed()
Marks the associated state manager as failed.

        afterImage.setVerificationFailed();