Annotation of Examples/EnterpriseObjects/DistributedEO/AppManager.m, revision 1.1.1.1

1.1       root        1: /*
                      2:    AppManager.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 "AppManager.h"
                     10: #import "Employee.h"
                     11: 
                     12: // A property added to the EMPLOYEE table in the PEOPLE demo database.
                     13: // This property is needed to avoid concurrent update to the same record.
                     14: #define lockProperty @"lock"
                     15: 
                     16: @interface AppManager(private)
                     17: - (void)_updateDisplay;
                     18: @end
                     19: 
                     20: @implementation AppManager(private)
                     21: 
                     22: // Responsible for keeping the lock button states up-to-date and to
                     23: // allow/disallow editing in the tableview. 
                     24: - (void)_updateDisplay
                     25: {
                     26:     id currentSelection = [[eoController selectedObjects] objectAtIndex:0];
                     27: 
                     28:     BOOL isEditable = [currentSelection isEditable];
                     29:     BOOL isLocked = [currentSelection isLocked];
                     30: 
                     31:     [lockButton setTitle:isLocked ? "Unlock" : "Lock"];
                     32:     [lockButton setEnabled:(!isLocked) || isEditable];
                     33: 
                     34:     [tableView setTarget:isLocked ? nil : lockButton]; 
                     35:     if([tableView isEditable] != isEditable) {
                     36:         [tableView setEditable:isEditable];
                     37:         if(!isEditable) {
                     38:             [tableView perform:@selector(display)
                     39:                           with:nil
                     40:                     afterDelay:0
                     41:                 cancelPrevious:NO];
                     42:         }
                     43:     }
                     44:     return;
                     45: }
                     46: 
                     47: @end
                     48: 
                     49: @implementation AppManager
                     50: 
                     51: // This notification is sent to AppManager by the DEONotificationCenter.
                     52: - (void)databaseChange:(DEONotification *)notification
                     53: {
                     54:     id eoObject = [notification notificationObject];
                     55: 
                     56:     if( !([EOFault isFault:eoObject] || [notification isLocal]) ) {
                     57:         EODatabaseDataSource *eoDatabasedataSource;
                     58:         EODatabaseChannel *eoDatabaseChannel;
                     59:         EODatabaseContext *eoDatabaseContext;
                     60:         BOOL autoTransaction = NO;
                     61: 
                     62:         eoDatabasedataSource =(EODatabaseDataSource*)[eoController dataSource];
                     63:         eoDatabaseChannel = [eoDatabasedataSource databaseChannel];
                     64:         eoDatabaseContext = [eoDatabaseChannel databaseContext];
                     65: 
                     66:         // refetch the EO from the database server to preserve data integrity.
                     67:         if (![eoDatabaseContext transactionNestingLevel]) {
                     68:             [eoDatabaseContext beginTransaction];
                     69:             autoTransaction = YES;
                     70:         }
                     71: 
                     72:         [eoDatabaseChannel refetchObject:eoObject];
                     73: 
                     74:         if (autoTransaction) [eoDatabaseContext commitTransaction];
                     75: 
                     76:         // redisplay the data. If editing is not ended, wait until it is done
                     77:         // (by changing the selection or the state of the lock)       
                     78:         if([tableView isEditable]) {
                     79:             needRedisplay = YES;
                     80:         } else {
                     81:             [eoController redisplay];
                     82:             [self _updateDisplay];
                     83:         }
                     84:     }
                     85:     return;
                     86: }
                     87: 
                     88: // Update the lock value in the database when lock button is pressed.
                     89: - toggleLockOnSelection:sender
                     90: {
                     91:     if([lockButton isEnabled]) {
                     92:         id currentSelection;
                     93:         NSArray *keys;
                     94:         NSMutableDictionary *objectValue;
                     95: 
                     96:         currentSelection = [[eoController selectedObjects] objectAtIndex:0];
                     97:         keys = [NSArray arrayWithObject:lockProperty];
                     98:         objectValue = [[[currentSelection valuesForKeys:keys] mutableCopy] autorelease];
                     99: 
                    100:         if([[objectValue objectForKey:lockProperty] isEqual:[EONull null]]) {
                    101:             [objectValue setObject:lockString forKey:lockProperty];
                    102:         } else {
                    103:             [objectValue setObject:[EONull null] forKey:lockProperty];
                    104:         }
                    105: 
                    106:         [eoController setValues:objectValue forObject:currentSelection];
                    107: 
                    108:         [self _updateDisplay];
                    109:     }
                    110:     return self;
                    111: }
                    112: @end
                    113: 
                    114: @implementation AppManager(EOControllerDelegate)
                    115: - (void)controllerDidChangeSelection:(EOController *)controller
                    116: {
                    117:     if(needRedisplay) {
                    118:         [eoController redisplay];
                    119:         needRedisplay = NO;
                    120:     }
                    121:     [self _updateDisplay];
                    122: }
                    123: @end
                    124: 
                    125: @implementation AppManager(EOApplicationDelegate)
                    126: - appDidInit:sender
                    127: {
                    128:     EODatabaseDataSource *eoDatabaseDataSource;
                    129:     EODatabaseChannel *eoDatabaseChannel;
                    130:     EOAdaptorContext *eoAdaptorContext;
                    131: 
                    132:     eoDatabaseDataSource = [eoController dataSource];
                    133:     eoDatabaseChannel = [eoDatabaseDataSource databaseChannel];
                    134:     eoAdaptorContext = [[eoDatabaseChannel adaptorChannel] adaptorContext];
                    135:     
                    136:     // Set up as the delegate of EOController, EODatabaseChannel,
                    137:     // and EOAdaptorContext
                    138:     [(EOController*)eoController setDelegate:self];
                    139:     [eoDatabaseChannel setDelegate:self]; // EO updates, inserts and deletes.
                    140:     [eoAdaptorContext setDelegate:self];  // Transactions begin, commit or rollback.
                    141: 
                    142:     // Put an ImageFormatter in column 0
                    143:     [[tableView columnAt:0] setFormatter:[[NXImageFormatter alloc] init]];
                    144: 
                    145:     // A double click will lock the current selection to start the
                    146:     // editing mode
                    147:     [tableView setTarget:lockButton];
                    148:     [tableView setDoubleAction:@selector(performClick:)];
                    149:     
                    150:     // Set up the Distributed Entreprise Object notification center
                    151:     deoNotificationCenter =
                    152:         [[DEONotificationCenter alloc]
                    153:                      initWithDatabaseChannel:eoDatabaseChannel
                    154:                                       entity:[eoDatabaseDataSource entity]];
                    155: 
                    156:     // Register for notification whenever objects of this entity are updated
                    157:     [deoNotificationCenter addObserver:self
                    158:                               selector:@selector(databaseChange:)
                    159:                       notificationName:DEOUpdate
                    160:                                 object:nil];
                    161: 
                    162:     // Update instance variables
                    163:     transactions = [NSMutableArray new];
                    164:     needRedisplay = NO;
                    165:     lockString = [[NSString alloc] initWithFormat:@"%s-%@-%d",
                    166:         NXUserName(),
                    167:         [DEONotificationCenter localHostname],
                    168:         NXProcessID];
                    169:     
                    170:     [Employee setLocalLockString:lockString];
                    171:     
                    172:     // Force the first fetch
                    173:     [eoController fetch:self];
                    174: 
                    175:     [self _updateDisplay];
                    176:     return self;
                    177: }
                    178: 
                    179: - appWillTerminate:sender
                    180: {
                    181:     [transactions release];
                    182:     [lockString release];
                    183:     [deoNotificationCenter removeObserver:self];
                    184:     [deoNotificationCenter release];
                    185:     return self;
                    186: }
                    187: @end
                    188: 
                    189: // We keep a list of all objects updated in the current transaction
                    190: // and post notification of the changes when the transaction commits.
                    191: // A more complete implementation could also keep track of insertions
                    192: // and deletions.
                    193: @implementation AppManager(EOAdaptorContextDelegate)
                    194: - (void)adaptorContextDidBegin:context
                    195: {
                    196:     [transactions addObject:[NSMutableArray array]];
                    197: }
                    198: 
                    199: - (void)adaptorContextDidCommit:context
                    200: {
                    201:     NSMutableDictionary *commitedTransaction = [transactions lastObject];
                    202:     id enumerator, current;
                    203: 
                    204:     [transactions removeLastObject];
                    205:     if([transactions count]) {
                    206:         [[transactions lastObject] addObjectsFromArray:commitedTransaction];
                    207:     } else {
                    208:         enumerator = [commitedTransaction objectEnumerator];
                    209:         while(current = [enumerator nextObject]) {
                    210:             [deoNotificationCenter postNotificationName:DEOUpdate object:current];
                    211:         }
                    212:     }
                    213: }
                    214: 
                    215: // If the transaction rolls back, there is no notification.
                    216: - (void)adaptorContextDidRollback:context
                    217: {
                    218:     [transactions removeLastObject];
                    219: }
                    220: 
                    221: @end
                    222: 
                    223: @implementation AppManager(EODatabaseChannelDelegate)
                    224: - (void)databaseChannel:channel didUpdateObject:anEO
                    225: {
                    226:     [(NSMutableArray *)[transactions lastObject] addObject:anEO];
                    227: }
                    228: @end

unix.superglobalmegacorp.com

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