Annotation of Examples/EnterpriseObjects/DistributedEO/DEOClient.subproj/DEONotificationCenter.m, revision 1.1

1.1     ! root        1: /*
        !             2:    DEONotificationCenter.m created by enoyau on Fri 13-Jan-1995
        !             3: 
        !             4:    You may freely copy, distribute, and reuse the code in this example.
        !             5:    NeXT disclaims any warranty of any kind, expressed or implied, as to its
        !             6:    fitness for any particular use.
        !             7: */
        !             8: 
        !             9: #import "DEONotificationCenter.h"
        !            10: #import "DEONotification.h"
        !            11: #import "DEOServerMonitor.h"
        !            12: #import <foundation/NSException.h>
        !            13: 
        !            14: #import <libc.h>
        !            15: 
        !            16: NSString *DEOUpdate = @"DEOUpdate";
        !            17: NSString *DEOInsert = @"DEOInsert";
        !            18: NSString *DEODelete = @"DEODelete";
        !            19: 
        !            20: @interface DEONotificationCenter(Communication) <DEOClient>
        !            21: - (void)registerAgain:(NSNotification *)note;
        !            22: @end
        !            23: 
        !            24: // Holder object to allow the server to retain the proxy to
        !            25: // a DEONotificationCenter without retaining the center itself.
        !            26: // See comment in initWithDatabaseChannel:entity:
        !            27: @interface DEONotificationCenterHolder : NSObject <DEOClient>
        !            28: {
        !            29:     DEONotificationCenter *center;
        !            30: }
        !            31: - initWithNonRetainedObject:(DEONotificationCenter *)aCenter;
        !            32: @end
        !            33: 
        !            34: 
        !            35: @implementation DEONotificationCenter
        !            36: 
        !            37: static NSString *localHostname = nil;
        !            38: 
        !            39: + initialize
        !            40: {
        !            41:     if(!localHostname) {
        !            42:         char DEOHostname[1024];
        !            43: 
        !            44:         gethostname(DEOHostname, 1024);
        !            45:         localHostname = [[NSString alloc] initWithCString:DEOHostname];
        !            46:     }
        !            47:     return self;
        !            48: }
        !            49: 
        !            50: + (NSString *)localHostname
        !            51: {
        !            52:     return localHostname;
        !            53: }
        !            54: 
        !            55: - initWithDatabaseChannel:(EODatabaseChannel *)aDatabaseChannel 
        !            56:                    entity:(EOEntity *)anEntity
        !            57: {
        !            58:     NSArray *objs;
        !            59:     NSArray *keys;
        !            60:     
        !            61:     [super init];
        !            62: 
        !            63:     // localCenter is used for notification.
        !            64:     localCenter = [[NSNotificationCenter alloc] init];
        !            65:     entity = [anEntity retain];
        !            66:     databaseChannel = [aDatabaseChannel retain];
        !            67: 
        !            68:     // Build the unique identifier for the DEONotificationCenter
        !            69:     objs = [NSArray arrayWithObjects:
        !            70:         localHostname,
        !            71:         [NSString stringWithFormat:@"%d", getpid()],
        !            72:         [anEntity name],
        !            73:         [NSString stringWithFormat:@"%x", self],
        !            74:         0];
        !            75: 
        !            76:     keys = [NSArray arrayWithObjects:
        !            77:         @"hostname",
        !            78:         @"pid",
        !            79:         @"entity",
        !            80:         @"self",
        !            81:         0];
        !            82: 
        !            83:     localID = [[NSDictionary dictionaryWithObjects:objs forKeys:keys] retain];
        !            84: 
        !            85:     // Register self for notifications from monitor
        !            86:     monitor = [[DEOServerMonitor serverMonitor] retain];
        !            87:     [[NSNotificationCenter defaultCenter] addObserver:self
        !            88:                                              selector:@selector(registerAgain:)
        !            89:                                      notificationName:DEOServerReinitialize
        !            90:                                                object:monitor];
        !            91: 
        !            92:     // We need to pass the server a pointer to our object, but it cannot
        !            93:     // retain it, or a cycle will be created.  Unfortunately, the server
        !            94:     // MUST retain the object we pass it or the proxy on the server side
        !            95:     // will be released.  The solution is to pass the server an "holder"
        !            96:     // object that it can retain (thus retaining the proxy) without
        !            97:     // retaining us (thus avoiding a cycle).  This holder must pass on
        !            98:     // messages to our actual instance.
        !            99:     container =
        !           100:         [[DEONotificationCenterHolder alloc] initWithNonRetainedObject:self];
        !           101: 
        !           102:     [self registerAgain:nil];
        !           103:     
        !           104:     return self;
        !           105: }
        !           106: 
        !           107: - (void)dealloc
        !           108: {
        !           109:     [localCenter release];
        !           110:     [entity release];
        !           111:     [databaseChannel release];
        !           112:     [localID release];
        !           113:     NS_DURING
        !           114:         [[monitor server] unregisterClient:(id <DEOClient>)container];
        !           115:     NS_HANDLER
        !           116:         NSLog(@"Failed to send remote method unregisterClient: to server.\n");
        !           117:     NS_ENDHANDLER
        !           118:     [container release];
        !           119:     [monitor release];
        !           120:     [super dealloc];
        !           121:     return;
        !           122: }
        !           123: 
        !           124: - (void)addObserver:observer
        !           125:            selector:(SEL)selector
        !           126:    notificationName:(NSString *)notificationName
        !           127:              object:object
        !           128: {
        !           129:     [localCenter addObserver:observer
        !           130:                     selector:selector
        !           131:             notificationName:notificationName
        !           132:                       object:object];
        !           133: }
        !           134: 
        !           135: - (void)removeObserver:observer
        !           136:       notificationName:(NSString *)notificationName
        !           137:                 object:object;
        !           138: {
        !           139:     [localCenter removeObserver:observer
        !           140:                notificationName:notificationName
        !           141:                          object:object];
        !           142: }
        !           143: 
        !           144: - (void)removeObserver:observer
        !           145: {
        !           146:     [localCenter removeObserver:observer];
        !           147: }
        !           148: 
        !           149: - (void)postNotificationName:(NSString *)notificationName object:object
        !           150: {
        !           151:     [self postNotificationName:notificationName object:object userInfo:nil];
        !           152: }
        !           153: 
        !           154: - (void)postNotificationName:(NSString *)name
        !           155:                       object:object
        !           156:                     userInfo:(NSDictionary *)userInfo;
        !           157: {
        !           158:     NSMutableDictionary *info = [NSMutableDictionary dictionary];
        !           159:     NSDictionary *primaryKey =
        !           160:         [entity primaryKeyForRow:[[[databaseChannel databaseContext] database] snapshotForObject:object]];
        !           161: 
        !           162:     // Encodes the enterprise object in a dictionary with the primary key.
        !           163:     [info setObject:primaryKey forKey:@"primaryKey"];
        !           164:     [info setObject:name       forKey:@"notificationName"];
        !           165:     [info setObject:localID    forKey:@"sender"];
        !           166: 
        !           167:     NS_DURING
        !           168:         [[monitor server] dispatchInformation:info
        !           169:                                        forKey:[entity name]
        !           170:                                      userInfo:userInfo];
        !           171:     NS_HANDLER
        !           172:             NSLog(@"Failed to send remote method dispatchInformation:forKey:userInfo: to server.\n");
        !           173:     NS_ENDHANDLER
        !           174: }
        !           175: 
        !           176: @end
        !           177: 
        !           178: @implementation DEONotificationCenter(Communication)
        !           179: 
        !           180: - (oneway)dispatchInformation:(NSDictionary *)info
        !           181:                        forKey:(NSString *)key
        !           182:                      userInfo:(NSDictionary *)userInfo
        !           183: {
        !           184:     // Decodes the enterprise object from information over the wire
        !           185:     id database = [[databaseChannel databaseContext] database];
        !           186:     id eoObject = [database objectForPrimaryKey:[info objectForKey:@"primaryKey"]
        !           187:                                          entity:entity];
        !           188: 
        !           189:     if(!eoObject) {
        !           190:         // Creates an EOFault if object does not exist yet
        !           191:         [EOFault objectFaultWithPrimaryKey:[info objectForKey:@"primaryKey"]
        !           192:                                     entity:entity
        !           193:                            databaseChannel:databaseChannel
        !           194:                                       zone:NSDefaultMallocZone()];
        !           195:     }
        !           196: 
        !           197:     [localCenter postNotification:
        !           198:         [DEONotification notificationWithName:[info objectForKey:@"notificationName"]
        !           199:                                        object:eoObject
        !           200:                                      userInfo:userInfo
        !           201:                                       isLocal:[[info objectForKey:@"sender"] isEqual:localID]]];
        !           202: 
        !           203:     return;
        !           204: }
        !           205: 
        !           206: // Is called at init time or when the server has died.
        !           207: - (void)registerAgain:(NSNotification *)note
        !           208: {
        !           209:     NS_DURING
        !           210:         // Register as entity user in the distributed server
        !           211:         [[monitor server] registerClient:(id <DEOClient>)container forKey:[entity name]];
        !           212:     NS_HANDLER
        !           213:         NSLog(@"Failed to send remote method registerClient:forKey: to server.\n");
        !           214:     NS_ENDHANDLER
        !           215: }
        !           216: 
        !           217: @end
        !           218: 
        !           219: @implementation DEONotificationCenterHolder
        !           220: 
        !           221: - initWithNonRetainedObject:(DEONotificationCenter *)aCenter
        !           222: {
        !           223:     [super init];
        !           224:     center = aCenter;
        !           225:     return self;
        !           226: }
        !           227: 
        !           228: - (oneway)dispatchInformation:(NSDictionary *)info
        !           229:                        forKey:(NSString *)key
        !           230:                      userInfo:(NSDictionary *)userInfo
        !           231: {
        !           232:     [center dispatchInformation:info
        !           233:                          forKey:key
        !           234:                        userInfo:userInfo];
        !           235: }
        !           236: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.