home *** CD-ROM | disk | FTP | other *** search
/ OpenStep (Enterprise) / OpenStepENTCD.toast / OEDEV / EODEV.Z / EOClassDescription.h < prev    next >
Encoding:
Text File  |  1996-09-11  |  13.2 KB  |  288 lines

  1. // EOClassDescription.h
  2. // Copyright (c) 1995, NeXT Software, Inc. All rights reserved. 
  3. //
  4. // The EOClassDescription provides a mechanism for extended all classes
  5. // with additional meta-data useful in interacting with Enterprise Objects.
  6. // It also allows this meta-information to be registered at runtime by an
  7. // external source (E.g. an EOEntity).  In effect, the EOClassDescription
  8. // allows EOF to add useful behavior to your EOs using information specified
  9. // for the EO in the EOModel file.
  10. //
  11. // For example, the Objective-C runtime allow the list of methods and instance
  12. // variables for a class to be queried at runtime (this is what makes possible
  13. // the EOKeyValueCoding protocol).  However, it does not provide information on
  14. // whether the property of an object is an attribute or relationship, nor whether
  15. // that relationship points to one or many objects -- this information is not
  16. // available in the source code, but is available in the EOModel.
  17. // Note, though, that although the EOModel is the most common source of a
  18. // ClassDescription for a class, it is not the only one.  Objects that don't
  19. // have a model can implement methods like "relationshipKeys" and "attributeKeys"
  20. // directly as instance methods, and the rest of the Framework can treat them
  21. // identically to EOs that have this information provided by an external model.
  22. //
  23. // In essense, the methods defined on NSObject here and the EOKeyValueCoding protocol
  24. // (valueForKey:, takeValue:forKey:), define the protocol for all communication
  25. // between the framework and your Enterprise Objects.
  26. //
  27. #import <EOControl/EOKeyValueCoding.h>
  28. #import <EOControl/EODefines.h>
  29.  
  30. @class EOEditingContext;
  31. @class EOGlobalID;
  32.  
  33. typedef enum
  34. {
  35.     EODeleteRuleNullify = 0,
  36.     EODeleteRuleCascade,
  37.     EODeleteRuleDeny
  38. } EODeleteRule;
  39.  
  40. @interface EOClassDescription : NSObject
  41.  
  42. + (void)registerClassDescription:(EOClassDescription *)description forClass:(Class)class;
  43.     // Register a classDescription object attached to the given class
  44.  
  45. + (void)invalidateClassDescriptionCache;
  46.     // should be called when a provider of class descriptions (like an EOModel)
  47.     // has newly become available, or is going away.
  48.  
  49. // Must be implemented by subclasses.
  50. - (NSString *)entityName;
  51.     // Return the name of the entity served by this class description
  52.  
  53. - (id)createInstanceWithEditingContext:(EOEditingContext *)editingContext globalID:(EOGlobalID *)globalID zone:(NSZone *)zone;
  54.     // Allocates an object of the appropriate class and if the object responds
  55.     // to "initWithEditingContext:classDescription:globalID" it invokes that
  56.     // method, otherwise it calls the method "init". Returns an autoreleased
  57.     // object.
  58.  
  59. - (void)awakeObject:(id)object fromInsertionInEditingContext:(EOEditingContext *)editingContext;
  60.     // Propagates inserts. New objects are created when they don't exist for any
  61.     // relationships that propagate the primary key.
  62.  
  63. - (void)awakeObject:(id)object fromFetchInEditingContext:(EOEditingContext *)editingContext;
  64.     // Default implementation simply returns.
  65.  
  66. - (void)propagateDeleteForObject:(id)object editingContext:(EOEditingContext *)editingContext;
  67.     // Called whenever a delete needs to be propagated.
  68.  
  69. - (NSArray *)attributeKeys;
  70.      // returns an array of keys for attributes of the EOs.  Attributes
  71.      // contain data (NSNumbers, NSStrings, ...) rather than pointers
  72.      // to other EOs.
  73. - (NSArray *)toOneRelationshipKeys;
  74. - (NSArray *)toManyRelationshipKeys;
  75.     // These methods return arrays of keys for the relationship
  76.     // properties of the receiver.  The toManyRelationshipKeys
  77.     // refer to properties containing NSArrays of pointers to
  78.     // other EOs.
  79.  
  80. - (NSString *)inverseForRelationshipKey:(NSString *)relationshipKey;
  81.     // Returns the name of the relationship pointing back at the receiver
  82.     // from the destination of the given relationship.  For example,
  83.     // [employee inverseForRelationshipKey:@"department"] might return
  84.     // @"employees" (such that this employee would appear in
  85.     // [[employee valueForKey:@"department"] valueForKey:@"employees"]
  86.  
  87. - (EODeleteRule)deleteRuleForRelationshipKey:(NSString *)relationshipKey;
  88.     // Returns a delete rule indicating how to treat the destination
  89.     // of the given relationship when the receiving object is deleted.
  90.     // For example, an Invoice might return EODeleteRuleCascade for
  91.     // the relationship @"lineItems" (when an invoice is removed from
  92.     // an external store, its line items should be as well).
  93.  
  94. - (BOOL)ownsDestinationObjectsForRelationshipKey:(NSString *)relationshipKey;
  95.     // Returns whether or not the objects in the destination of the given
  96.     // relationship should be deleted if they are removed from the relationship
  97.     // (and not added to the cooresponding relationship of another object).
  98.     // E.g. if a LineItem is removed from an Invoice it should be deleted.
  99.  
  100. - (EOClassDescription *)classDescriptionForDestinationKey:(NSString *)detailKey;
  101.     // Returns the class description for objects at the destination of the
  102.     // given relationship.  E.g. [project classDescriptionForDestinationKey:@"leader"]
  103.     // might return the class description for the Employee class.
  104.  
  105. - (NSException *)validateValue:(id *)valueP forKey:(NSString *)key;
  106.     // Validate value pointed to by valueP.  Return nil if value is okay,
  107.     // or an unevaluated exception containing a user-presentable
  108.     // (localized) error message if not.  May replace *valueP with a converted
  109.     // value (e.g. the EOAttribute may convert a string to an NSNumber).
  110.  
  111. - (NSException *)validateObjectForSave:(id)object;
  112.     // Validate the object. Return nil if object is okay,
  113.     // or an unraised exception containing a user-presentable
  114.     // (localized) error message if not.
  115.  
  116. - (NSException *)validateObjectForDelete:(id)object;
  117.     // Check if it's posible to delete the object. Return nil if it
  118.     // is okay, or an unevaluated exception containing a user-presentable
  119.     // (localized) error message if not.
  120.  
  121. @end
  122.  
  123.  
  124. //
  125. // This informal protocol defines the initialization method which may be
  126. // implemented by enterprise objects.  If this method is not implemented by
  127. // an enterprise object init is used.
  128. //
  129. @interface NSObject (EOInitialization)
  130.  
  131. - initWithEditingContext:(EOEditingContext *)ec classDescription:(EOClassDescription *)classDesc globalID:(EOGlobalID *)globalID;
  132.    // Method used to initialize eo's created by the framework. If the eo
  133.    // doesn't implement this method then init is called instead.
  134.  
  135. @end
  136.  
  137. @interface NSObject (EOClassDescriptionPrimitives)
  138.  
  139. - (EOClassDescription *)classDescription;
  140.     // default implementation looks for a class description registered for
  141.     // this objects class.  EOGenericRecord returns the class description
  142.     // for its entity.
  143.  
  144. - (NSString *)entityName;
  145. - (NSArray *)attributeKeys;
  146. - (NSArray *)toOneRelationshipKeys;
  147. - (NSArray *)toManyRelationshipKeys;
  148. - (NSString *)inverseForRelationshipKey:(NSString *)relationshipKey;
  149. - (EODeleteRule)deleteRuleForRelationshipKey:(NSString *)relationshipKey;
  150. - (BOOL)ownsDestinationObjectsForRelationshipKey:(NSString *)relationshipKey;
  151. - (EOClassDescription *)classDescriptionForDestinationKey:(NSString *)detailKey;
  152.     // The default implementations of these methods look for a [self classDescription]
  153.     // object and pass the method on to it.
  154.  
  155. - (NSException *)validateValue:(id *)valueP forKey:(NSString *)key;
  156.     // Default implementation calls:
  157.     //     [[self classDescription] validateValue:valueP forKey:key];
  158.     // and, if no error, looks for an implementation of the form:
  159.     //    - (NSException *)validateSalary:(id)value
  160.     // corresponding to the given key.
  161.  
  162. - (NSException *)validateForSave;
  163.     // called by the default implementations validateForInsert and validateForUpdate
  164.     // The default implementation calls validateValue:forKey: for all attributes
  165.     // and relationship keys on the object and then calls 
  166.     //     [[self classDescription] validateObjectForSave:self].
  167.     // Validation is continued for all keys, even after an initial failure.  If more
  168.     // than one validation error occurred, the exception returned contains
  169.     // is prepared by [NSException aggregateExceptionWithExceptions:] (see below).
  170.  
  171. - (NSException *)validateForDelete;
  172.     // Validate whether object can be deleted
  173.     // The default implementation calls [[self classDescription] validateDeleteForObject:self]
  174.  
  175. - (void)awakeFromInsertionInEditingContext:(EOEditingContext *)editingContext;
  176.     // Invoked on newly created eo's (i.e. objects that are not being initialized
  177.     // from persistent data). The NSObject implementation of this method simply
  178.     // calls the corresponding method on EOClassDescription.
  179.  
  180. - (void)awakeFromFetchInEditingContext:(EOEditingContext *)editingContext;
  181.     // Invoked on eo's that are created from their persistent statue. For example,
  182.     // when data is fetched the database or some other object store. This method is
  183.     // called after the object has been initialized and loaded with data. The
  184.     // NSObject implementation of this method simply calls the corresponding method
  185.     // on EOClassDescription.
  186.  
  187. @end
  188.  
  189. // Notifications:
  190. EOCONTROL_EXTERN NSString *EOClassDescriptionNeededNotification;
  191.     // when the default implementation of classDescription is called
  192.     // on an unregistered class, this notification is broadcast.
  193.     // Subscribers can call [EOClassDescription registerClassDescription:forClass:]
  194.     // to register the class description.
  195.  
  196. //
  197. // implemented in terms of the primitives in NSObject (EOClassDescriptionPrimitives)
  198. //
  199. @interface NSObject (EOClassDescriptionExtras)
  200.  
  201. - (NSDictionary *)snapshot;
  202.     // uses values for keys to extract snapshot of attributeKeys
  203.     // toOneRelationshipKeys, toManyRelationshipKeys
  204.  
  205. - (void)updateFromSnapshot:(NSDictionary *)snapshot;
  206.     // [self takeValuesFromDictionary:snapshot];
  207.  
  208. - (BOOL)isToManyKey:(NSString *)key;
  209.     // lookup in toManyRelationshipKeys;
  210.  
  211. - (NSException *)validateForInsert;
  212. - (NSException *)validateForUpdate;
  213.     // [self validateForSave]
  214.  
  215. - (NSArray *)allPropertyKeys;
  216.     // default unions attributeKeys, toOneRelationshipKeys, and toManyRelationshipKeys
  217.  
  218. - (void)clearProperties;
  219.     // Reset all properties to nil. Used to refaut an object.
  220.     // Could be used to broke circular references
  221.  
  222. - (void)propagateDeleteWithEditingContext:(EOEditingContext *)editingContext;
  223.     // NSObject implementation of this method simply calls the corresponding method
  224.     // on EOClassDescription.
  225.  
  226. - (NSString *)eoShallowDescription;
  227. - (NSString *)eoDescription;
  228.     // Useful debugging methods for printing out EOs.
  229.     // eoShallowDescription returns a simple string with the object's className,
  230.     // entityName and memory address.
  231.     // eoDescription extracts all of the values from the receiver using the
  232.     // EOKeyValueCoding protocol and asks the destination of every relationship
  233.     // property for its eoShallowDescription.  (By calling eoShallowDescription
  234.     // on its relationships rather than eoDescription, eoDescription avoids
  235.     // infinite recursion for cyclical graphs of objects).
  236.     //
  237.     // If you want eoDescription to be used on a class when you po it in gdb,
  238.     // add the following to your EO:
  239.     // - (NSString *)description { return [self eoDescription]; }
  240.     // (You could also define a shortcut print macro in your ~/.gdbinit like
  241.     //  the following:
  242.     // define peo
  243.     //   po [$arg0 eoDescription]
  244.     // end
  245.  
  246.  
  247. @end
  248.  
  249. @interface NSObject (EOKeyRelationshipManipulation)
  250.  
  251. - (void)addObject:object toPropertyWithKey:(NSString *)key;
  252.     // adds the given object to the given array property.  For the key "projects",
  253.     // the default implementation would look for method with name addToProjects:
  254.     // and if not found would look for a property called "projects" (via valueForKey:)
  255.     // In the latter case, the object would be added to array (if it was an
  256.     // NSMutableArray).  Otherwise a new array including the new element would be set
  257.     // on the object.
  258.  
  259. - (void)removeObject:object fromPropertyWithKey:(NSString *)key;
  260.     // Like addObject:toPropertyWithKey:.  Looks for selector of form
  261.     // removeFromProjects:
  262.  
  263.     // Implemented in terms of the above, plus inverseForRelationshipKey, & isToManyKey...
  264. - (void)addObject:object toBothSidesOfRelationshipWithKey:(NSString *)key;
  265. - (void)removeObject:object fromBothSidesOfRelationshipWithKey:(NSString *)key;
  266.     // These methods to the right thing whether the source relationship is
  267.     // to-one or to-many, and whether the reciprocal relationship is to-one
  268.     // or to many.
  269.     // [eo addObject:o toBothSidesOfRelationshipWithKey:@"toOneRelName"] will
  270.     // remove the current object set on the to-one relationship (removing its
  271.     // back pointer) and set the new object (and set its back pointer).
  272.  
  273. @end
  274.  
  275. // Convenience for constructing validation exceptions
  276. // (with name EOValidationException)
  277. EOCONTROL_EXTERN NSString *EOValidationException;
  278.  
  279. @interface NSException (EOValidationError)
  280. + (NSException *)validationExceptionWithFormat:(NSString *)format, ...;
  281. + (NSException *)aggregateExceptionWithExceptions:(NSArray *)subexceptions;
  282.     // returns an exception with the name, reason, and userInfo of the first
  283.     // exception in the array, but with the userInfo augmented with the list of
  284.     // subexceptions under the key EOAdditionalExceptionsKey
  285.  
  286. EOCONTROL_EXTERN NSString *EOAdditionalExceptionsKey;
  287. @end
  288.