Hi all,

Some time ago I noticed that validaetForDelete() does not work properly in client side EOCustomObject's implementation. It turns out that the bug is in EOClassDescription.validateObjectForDelete (EOEnterpriseObject), which does not properly check relationships against deletion rules. The deletion rules however are present in the class description, so I overrode validateForDelete() in my common EO superclass. I have reported this bug quite some time ago, but it still is not fixed. Anyway, for anyone who might fight the same problem, the implementation is below. My first tests show that this works OK. Please let me know however if you find any mistakes in it.

Cheers,
Flor



        /**
        *       Overriden because the client side implementation of
* <tt>EOClassDescription.validateObjectForDelete(EOEnterpriseObject) </tt> does not
        *       perform proper checking against deletion rules.<p>
        *
* This implementation first invoked the superclass' implementation (which might throw), * and thereafter checks manually for relationship deletion rules and this object's
        *       relationship, to verify that the object indeed is valid for 
deletion.
        *
@throws NSValidation.ValidationException If the object is in an invalid state
                        for deletion
        */
        public void validateForDelete(){
                
                //      exception aggregation
                NSMutableArray allExceptions = null;
                
                //      superclass implementation
                try{
                        super.validateForDelete();
                }catch(NSValidation.ValidationException ex){
                        allExceptions = new NSMutableArray();
                        allExceptions.addObject(ex);
                }
                
                //      get the relationships keys
                NSArray toOneRelationshipKeys = toOneRelationshipKeys(),
                        toManyRelationshipKeys = toManyRelationshipKeys();
                
                //      get the class description, needed for deletion rule 
checking
                EOClassDescription cd = classDescription();
                        
                //      iterate through the to one relationship keys
                for(int i = 0 ; i < toOneRelationshipKeys.count() ; i++){
                        String key = 
(String)toOneRelationshipKeys.objectAtIndex(i);
                        int deleteRule = cd.deleteRuleForRelationshipKey(key);
                        
// if it is a deny delete rule for a relationship where the destination is
                        //      not null, the object is invalid for deletion
                        if(deleteRule == EOClassDescription.DeleteRuleDeny){
                                if(valueForKey(key) != null){
                                        //      add an exception to the list
                                        if(allExceptions == null) allExceptions 
= new NSMutableArray();
                                        allExceptions.addObject(new 
NSValidation.ValidationException(
                                                "Can not delete a "+entityName()+" 
that has a related "+key,
                                                valueForKey(key),
                                                key));
                                }
                        
// if it is a cascade delete rule, we need to make sure that if there is a
                        //      related object, it also is valid for deletion
                        }else if(deleteRule == 
EOClassDescription.DeleteRuleCascade){
                                Object relatedObject = valueForKey(key);
                                if(relatedObject != null){
                                        try{
                                                
((EOValidation)relatedObject).validateForDelete();
                                        }catch(NSValidation.ValidationException 
ex){
                                                //      add an exception to the 
list
                                                if(allExceptions == null) 
allExceptions = new NSMutableArray();
                                                allExceptions.addObject(new 
NSValidation.ValidationException(
                                                        "Can not delete a 
"+entityName()+" that has a related "+key+
                                                                " which isn't valid 
for deletion",
                                                        valueForKey(key),
                                                        key));
                                        }
                                }
                        }
                }//     toOneRelationships loop
                
                
                //      iterate through the to many relationship keys
                for(int i = 0 ; i < toManyRelationshipKeys.count() ; i++){
                        String key = 
(String)toManyRelationshipKeys.objectAtIndex(i);
                        int deleteRule = cd.deleteRuleForRelationshipKey(key);
                        
// if it is a deny delete rule for a relationship where the destination is
                        //      not null, the object is invalid for deletion
                        if(deleteRule == EOClassDescription.DeleteRuleDeny){
                                if(((Integer)valueForKeyPath(key + "[EMAIL 
PROTECTED]")).intValue() != 0){
                                        //      add an exception to the list
                                        if(allExceptions == null) allExceptions 
= new NSMutableArray();
                                        allExceptions.addObject(new 
NSValidation.ValidationException(
"Can not delete a "+entityName()+" that has related "+key+" records",
                                                valueForKey(key),
                                                key));
                                }
                        
// if it is a cascade delete rule, we need to make sure that if there is a
                        //      related object, it also is valid for deletion
                        }else if(deleteRule == 
EOClassDescription.DeleteRuleCascade){
                                NSArray relatedObjects = 
(NSArray)valueForKey(key);
                                int count = relatedObjects.count();
                                int j = 0;
                                try{
                                        for( ; j < count ; j++)
((EOValidation)relatedObjects.objectAtIndex (j)).validateForDelete();
                                }catch(NSValidation.ValidationException ex){
                                        //      add an exception to the list
                                        if(allExceptions == null) allExceptions 
= new NSMutableArray();
                                        allExceptions.addObject(new 
NSValidation.ValidationException(
"Can not delete a "+entityName()+" because one of the objects in the "+
                                                        key+" relationship isn't 
valid for deletion",
                                                relatedObjects.objectAtIndex(j),
                                                key));
                                }
                        }
                }//     toManyRelationships loop
                
                //      check if there is something to throw
                if(allExceptions != null && allExceptions.count() != 0)
throw NSValidation.ValidationException.aggregateExceptionWithExceptions (allExceptions);
                
                //      valid for deletion!
        }
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to