FileDocCategorySizeDatePackage
DescriptorEvent.javaAPI DocGlassfish v2 API21079Tue May 22 16:54:16 BST 2007oracle.toplink.essentials.descriptors

DescriptorEvent

public class DescriptorEvent extends EventObject

Purpose: Encapsulate the information provided with descriptor events. This is used as the argument to any event raised by the descriptor. Events can be registered for, through two methods, the first is by providing a method to be called on the object that a paticular operation is being performed on. The second is by registering an event listener to be notified when any event occurs for that descriptor. The second method is more similar to the java beans event model and requires the registered listener to implement the DescriptorEventListener interface.

see
DescriptorEventManager
see
DescriptorEventListener
see
DescriptorEventAdapter

Fields Summary
protected int
eventCode
The code of the descriptor event being raised. This is an integer constant value from DescriptorEventManager.
protected DatabaseQuery
query
The query causing the event.
protected Record
record
Optionally a database row may be provided on some events, (such as aboutToUpdate).
protected ClassDescriptor
descriptor
protected Object
originalObject
The source object represents the object the event is being raised on, some events also require a second object, for example the original object in a postClone.
protected ObjectChangeSet
changeSet
For the post merge event it is possible that there has been a change set generated. This attribute will store the changeSet for the object just merged
protected AbstractSession
session
The session in which the event is raised.
protected static String[]
eventNames
Event names for toString()
Constructors Summary
public DescriptorEvent(int eventCode, ObjectLevelModifyQuery query)
PUBLIC: Most events are trigger from queries, so this is a helper method.

        eventNames = new String[DescriptorEventManager.NumberOfEvents];

        eventNames[DescriptorEventManager.PreWriteEvent] = "PreWriteEvent";
        eventNames[DescriptorEventManager.PostWriteEvent] = "PostWriteEvent";
        eventNames[DescriptorEventManager.PreDeleteEvent] = "PostDeleteEvent";
        eventNames[DescriptorEventManager.PostDeleteEvent] = "PostDeleteEvent";
        eventNames[DescriptorEventManager.PreInsertEvent] = "PreInsertEvent";
        eventNames[DescriptorEventManager.PostInsertEvent] = "PostInsertEvent";
        eventNames[DescriptorEventManager.PreUpdateEvent] = "PreUpdateEvent";
        eventNames[DescriptorEventManager.PostUpdateEvent] = "PostUpdateEvent";
        eventNames[DescriptorEventManager.PostBuildEvent] = "PostBuildEvent";
        eventNames[DescriptorEventManager.PostRefreshEvent] = "PostRefreshEvent";
        eventNames[DescriptorEventManager.PostCloneEvent] = "PostCloneEvent";
        eventNames[DescriptorEventManager.PostMergeEvent] = "PostMergeEvent";
        eventNames[DescriptorEventManager.AboutToInsertEvent] = "AboutToInsertEvent";
        eventNames[DescriptorEventManager.AboutToUpdateEvent] = "AboutToUpdateEvent";
    
        this(query.getObject());
        this.query = query;
        this.eventCode = eventCode;
        this.session = query.getSession();
        this.descriptor = query.getDescriptor();
    
public DescriptorEvent(Object sourceObject)
PUBLIC: All events require a source object.

        super(sourceObject);
    
Methods Summary
public voidapplyAttributeValuesIntoRow(java.lang.String attributeName)
PUBLIC: Re-populate the database row with the values from the source object based upon the attribute's mapping. Provided as a helper method for modifying the row during event handling.

        ClassDescriptor descriptor = getSession().getDescriptor(getSource());
        DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeName);

        if (mapping == null) {
            throw ValidationException.missingMappingForAttribute(descriptor, attributeName, this.toString());
        }
        if (getRecord() != null) {
            mapping.writeFromObjectIntoRow(getSource(), (AbstractRecord)getRecord(), getSession());
        }
    
public oracle.toplink.essentials.internal.sessions.ObjectChangeSetgetChangeSet()
PUBLIC: Returns the Object changeSet if available

        return changeSet;
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetClassDescriptor()
PUBLIC: The source descriptor of the event.

		ClassDescriptor desc = getDescriptor();
		if (desc instanceof ClassDescriptor) {
			return (ClassDescriptor)desc;
		} else {
			throw ValidationException.cannotCastToClass(desc, desc.getClass(), ClassDescriptor.class);
		}
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetDescriptor()
PUBLIC: The source descriptor of the event.

        return descriptor;
    
public intgetEventCode()
PUBLIC: The code of the descriptor event being raised. This is an integer constant value from DescriptorEventManager.

        return eventCode;
    
public java.lang.ObjectgetObject()
PUBLIC: Synanym for source.

        return getSource();
    
public java.lang.ObjectgetOriginalObject()
PUBLIC: The source object represents the object the event is being raised on, some events also require a second object, for example the original object in a postClone.

see
EventObject#getSource()

        // Compute the original for unit of work writes.
        if ((originalObject == null) && getSession().isUnitOfWork() && (getQuery() != null) && (getQuery().isObjectLevelModifyQuery())) {
            setOriginalObject(((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(getSource()));
        }
        return originalObject;
    
public oracle.toplink.essentials.queryframework.DatabaseQuerygetQuery()
PUBLIC: The query causing the event.

        return query;
    
public oracle.toplink.essentials.sessions.RecordgetRecord()
PUBLIC: Return the record that is associated with some events, such as postBuild, and aboutToUpdate.

        return record;
    
public oracle.toplink.essentials.internal.sessions.AbstractSessiongetSession()
PUBLIC: The session in which the event is raised.

        return session;
    
public voidsetChangeSet(oracle.toplink.essentials.internal.sessions.ObjectChangeSet newChangeSet)
INTERNAL: Sets the Change set in the event if the change Set is available

        changeSet = newChangeSet;
    
public voidsetDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor descriptor)
INTERNAL: The source descriptor of the event.

        this.descriptor = descriptor;
    
public voidsetEventCode(int eventCode)
INTERNAL: The code of the descriptor event being raised. This is an integer constant value from DescriptorEventManager.

        this.eventCode = eventCode;
    
public voidsetOriginalObject(java.lang.Object originalObject)
INTERNAL: The source object represents the object the event is being raised on, some events also require a second object, for example the original object in a postClone.

        this.originalObject = originalObject;
    
public voidsetQuery(oracle.toplink.essentials.queryframework.DatabaseQuery query)
INTERNAL: The query causing the event.

        this.query = query;
    
public voidsetRecord(oracle.toplink.essentials.sessions.Record record)
INTERNAL: Optionally a database row may be provided on some events, (such as aboutToUpdate).

        this.record = record;
    
public voidsetSession(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: The session in which the event is raised.

        this.session = session;
    
public java.lang.StringtoString()
INTERNAL:

        String eventName = "UnkownEvent";

        if ((getEventCode() >= 0) && (getEventCode() < DescriptorEventManager.NumberOfEvents)) {
            eventName = eventNames[getEventCode()];
        }

        return eventName + "(" + getSource().getClass() + ")";
    
public voidupdateAttributeAddObjectToCollection(java.lang.String attributeName, java.lang.Object mapKey, java.lang.Object value)
ADVANCED: Use this method when updating object attribute values, with unmapped objects Integer, String or others. in events to ensure that all required objects are updated. TopLink will automaticaly update all objects and changesets envolved. TopLink will update the field, in the row, to have the new value for the field that this mapping maps to. If the attribute being updated is within an aggregate then pass the updated aggregate and the attribute of the aggregate mapping into this method.

        DatabaseMapping mapping = this.query.getDescriptor().getMappingForAttributeName(attributeName);
        if (mapping == null) {
            throw DescriptorException.mappingForAttributeIsMissing(attributeName, getDescriptor());
        }

        Object clone = this.getObject();
        Object cloneValue = value;
        Object original = null;

        //only set the original object if we need to update it, ie before the merge takes place
        if ((this.eventCode == DescriptorEventManager.PostCloneEvent) || (this.eventCode == DescriptorEventManager.PostMergeEvent)) {
            original = this.getOriginalObject();
        }
        Object originalValue = value;
        ObjectChangeSet eventChangeSet = this.getChangeSet();
        Object valueForChangeSet = value;

        if ((this.query != null) && this.query.isObjectLevelModifyQuery()) {
            clone = ((ObjectLevelModifyQuery)this.query).getObject();
            eventChangeSet = ((ObjectLevelModifyQuery)this.query).getObjectChangeSet();
        }
        ClassDescriptor descriptor = getSession().getDescriptor(value.getClass());

        if (descriptor != null) {
            //There is a descriptor for the value being passed in so we must be carefull
            // to convert the value before assigning it.
            if (eventChangeSet != null) {
                valueForChangeSet = descriptor.getObjectBuilder().createObjectChangeSet(value, (UnitOfWorkChangeSet)eventChangeSet.getUOWChangeSet(), getSession());
            }
            if (original != null) {
                // must be a unitOfWork because only the postMerge, and postClone events set this attribute
                originalValue = ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(value);
            }
        }

        if (clone != null) {
            Object collection = mapping.getRealCollectionAttributeValueFromObject(clone, getSession());
            mapping.getContainerPolicy().addInto(mapKey, cloneValue, collection, getSession());
        }
        if (original != null) {
            Object collection = mapping.getRealCollectionAttributeValueFromObject(original, getSession());
            mapping.getContainerPolicy().addInto(mapKey, originalValue, collection, getSession());
        }
        if (getRecord() != null) {
            AbstractRecord tempRow = getDescriptor().getObjectBuilder().createRecord();

            // pass in temp Row because most mappings use row.add() not row.put() for
            // perf reasons.  We are using writeFromObjectIntoRow in order to support
            // a large number of types.
            mapping.writeFromObjectIntoRow(clone, tempRow, getSession());
            ((AbstractRecord)getRecord()).mergeFrom(tempRow);
        }
        if (eventChangeSet != null) {
            mapping.simpleAddToCollectionChangeRecord(mapKey, valueForChangeSet, eventChangeSet, getSession());
        }
    
public voidupdateAttributeRemoveObjectFromCollection(java.lang.String attributeName, java.lang.Object mapKey, java.lang.Object value)
ADVANCED: Use this method when updating object attribute values, with unmapped objects Integer, String or others. in events to ensure that all required objects are updated. TopLink will automaticaly update all objects and changesets envolved. TopLink will update the field, in the row, to have the new value for the field that this mapping maps to.

        DatabaseMapping mapping = this.query.getDescriptor().getMappingForAttributeName(attributeName);
        if (mapping == null) {
            throw DescriptorException.mappingForAttributeIsMissing(attributeName, getDescriptor());
        }

        Object clone = this.getObject();
        Object cloneValue = value;
        Object original = null;

        //only set the original object if we need to update it, ie before the merge takes place
        if ((this.eventCode == DescriptorEventManager.PostCloneEvent) || (this.eventCode == DescriptorEventManager.PostMergeEvent)) {
            original = this.getOriginalObject();
        }
        Object originalValue = value;
        ObjectChangeSet eventChangeSet = this.getChangeSet();
        Object valueForChangeSet = value;

        if ((this.query != null) && this.query.isObjectLevelModifyQuery()) {
            clone = ((ObjectLevelModifyQuery)this.query).getObject();
            eventChangeSet = ((ObjectLevelModifyQuery)this.query).getObjectChangeSet();
        }
        ClassDescriptor descriptor = getSession().getDescriptor(value.getClass());

        if (descriptor != null) {
            //There is a descriptor for the value being passed in so we must be carefull
            // to convert the value before assigning it.
            if (eventChangeSet != null) {
                valueForChangeSet = descriptor.getObjectBuilder().createObjectChangeSet(value, (UnitOfWorkChangeSet)eventChangeSet.getUOWChangeSet(), getSession());
            }
            if (original != null) {
                // must be a unitOfWork because only the postMerge, and postClone events set this attribute
                originalValue = ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(value);
            }
        }
        if (clone != null) {
            Object collection = mapping.getRealCollectionAttributeValueFromObject(clone, getSession());
            mapping.getContainerPolicy().removeFrom(mapKey, cloneValue, collection, getSession());
        }
        if (original != null) {
            Object collection = mapping.getRealCollectionAttributeValueFromObject(original, getSession());
            mapping.getContainerPolicy().removeFrom(mapKey, originalValue, collection, getSession());
        }
        if (getRecord() != null) {
            AbstractRecord tempRow = getDescriptor().getObjectBuilder().createRecord();

            // pass in temp Row because most mappings use row.add() not row.put() for
            // perf reasons.  We are using writeFromObjectIntoRow in order to support
            // a large number of types.
            mapping.writeFromObjectIntoRow(clone, tempRow, getSession());
            ((AbstractRecord)getRecord()).mergeFrom(tempRow);
        }
        if (eventChangeSet != null) {
            mapping.simpleRemoveFromCollectionChangeRecord(mapKey, valueForChangeSet, eventChangeSet, getSession());
        }
    
public voidupdateAttributeWithObject(java.lang.String attributeName, java.lang.Object value)
ADVANCED: Use this method when updating object attribute values, with unmapped objects Integer, String or others. in events to ensure that all required objects are updated. TopLink will automaticaly update all objects and changesets envolved. TopLink will update the field, in the row, to have the new value for the field that this mapping maps to.

        DatabaseMapping mapping = this.query.getDescriptor().getMappingForAttributeName(attributeName);
        if (mapping == null) {
            throw DescriptorException.mappingForAttributeIsMissing(attributeName, getDescriptor());
        }

        Object clone = this.getObject();
        Object cloneValue = value;
        Object original = null;

        //only set the original object if we need to update it, ie before the merge takes place
        if ((this.eventCode == DescriptorEventManager.PostCloneEvent) || (this.eventCode == DescriptorEventManager.PostMergeEvent)) {
            original = this.getOriginalObject();
        }
        Object originalValue = value;
        ObjectChangeSet eventChangeSet = this.getChangeSet();
        Object valueForChangeSet = value;

        if ((this.query != null) && this.query.isObjectLevelModifyQuery()) {
            clone = ((ObjectLevelModifyQuery)this.query).getObject();
            eventChangeSet = ((ObjectLevelModifyQuery)this.query).getObjectChangeSet();
        }
        ClassDescriptor descriptor = getSession().getDescriptor(value.getClass());

        if (descriptor != null) {
            //There is a descriptor for the value being passed in so we must be carefull
            // to convert the value before assigning it.
            if (eventChangeSet != null) {
                valueForChangeSet = descriptor.getObjectBuilder().createObjectChangeSet(value, (UnitOfWorkChangeSet)eventChangeSet.getUOWChangeSet(), getSession());
            }
            if (original != null) {
                // must be a unitOfWork because only the postMerge, and postClone events set this attribute
                originalValue = ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(value);
            }
        }
        if (clone != null) {
            mapping.setRealAttributeValueInObject(clone, cloneValue);
        }
        if (original != null) {
            mapping.setRealAttributeValueInObject(original, originalValue);
        }
        if (getRecord() != null) {
            AbstractRecord tempRow = getDescriptor().getObjectBuilder().createRecord();

            // pass in temp Row because most mappings use row.add() not row.put() for
            // perf reasons.  We are using writeFromObjectIntoRow in order to support
            // a large number of types.
            mapping.writeFromObjectIntoRow(clone, tempRow, getSession());
            ((AbstractRecord)getRecord()).mergeFrom(tempRow);
        }
        if (eventChangeSet != null) {
            eventChangeSet.removeChange(attributeName);
            eventChangeSet.addChange(mapping.compareForChange(clone, ((UnitOfWorkImpl)getSession()).getBackupClone(clone), eventChangeSet, getSession()));
        }