Permalink
Browse files

Initial import

Copied from https://onebusaway-iphone.googlecode.com/svn/trunk/, rev. 2 by bdferris @ 7/31/2009 6:10 PM
  • Loading branch information...
1 parent cf63c1f commit b2fc566c7ae1bf7d290bdcdedce63fbdacb948b6 @bdferris bdferris committed Sep 17, 2010
Showing with 16,939 additions and 0 deletions.
  1. +43 −0 Classes/ActivityRecognition/Control/OBAActivityLogger.h
  2. +196 −0 Classes/ActivityRecognition/Control/OBAActivityLogger.m
  3. +41 −0 Classes/ActivityRecognition/Control/OBARotatingLogger.h
  4. +128 −0 Classes/ActivityRecognition/Control/OBARotatingLogger.m
  5. +53 −0 Classes/ActivityRecognition/Control/OBAUploadManager.h
  6. +203 −0 Classes/ActivityRecognition/Control/OBAUploadManager.m
  7. +29 −0 Classes/ActivityRecognition/View/OBAActivityAnnotationViewController.h
  8. +91 −0 Classes/ActivityRecognition/View/OBAActivityAnnotationViewController.m
  9. +28 −0 Classes/ActivityRecognition/View/OBAActivityLoggingViewController.h
  10. +102 −0 Classes/ActivityRecognition/View/OBAActivityLoggingViewController.m
  11. +58 −0 Classes/ActivityRecognition/View/OBALockViewController.h
  12. +204 −0 Classes/ActivityRecognition/View/OBALockViewController.m
  13. +38 −0 Classes/ActivityRecognition/View/OBAUploadViewController.h
  14. +127 −0 Classes/ActivityRecognition/View/OBAUploadViewController.m
  15. +26 −0 Classes/Control/DataSource/OBADataSource.h
  16. +30 −0 Classes/Control/DataSource/OBADataSourceConfig.h
  17. +61 −0 Classes/Control/DataSource/OBADataSourceConfig.m
  18. +34 −0 Classes/Control/DataSource/OBAJsonDataSource.h
  19. +275 −0 Classes/Control/DataSource/OBAJsonDataSource.m
  20. +28 −0 Classes/Control/Digester/OBACreateManagedEntityJsonDigesterRule.h
  21. +165 −0 Classes/Control/Digester/OBACreateManagedEntityJsonDigesterRule.m
  22. +26 −0 Classes/Control/Digester/OBACreateObjectJsonDigesterRule.h
  23. +42 −0 Classes/Control/Digester/OBACreateObjectJsonDigesterRule.m
  24. +57 −0 Classes/Control/Digester/OBAJsonDigester.h
  25. +218 −0 Classes/Control/Digester/OBAJsonDigester.m
  26. +31 −0 Classes/Control/Digester/OBASetCoordinatePropertyJsonDigesterRule.h
  27. +88 −0 Classes/Control/Digester/OBASetCoordinatePropertyJsonDigesterRule.m
  28. +26 −0 Classes/Control/Digester/OBASetNextOBAJsonDigesterRule.h
  29. +36 −0 Classes/Control/Digester/OBASetNextOBAJsonDigesterRule.m
  30. +26 −0 Classes/Control/Digester/OBASetPropertyJsonDigesterRule.h
  31. +39 −0 Classes/Control/Digester/OBASetPropertyJsonDigesterRule.m
  32. +42 −0 Classes/Control/OBAActivityListeners.h
  33. +86 −0 Classes/Control/OBAActivityListeners.m
  34. +70 −0 Classes/Control/OBACommon.h
  35. +72 −0 Classes/Control/OBACommon.m
  36. +21 −0 Classes/Control/OBAErrorSource.h
  37. +45 −0 Classes/Control/OBALocationManager.h
  38. +88 −0 Classes/Control/OBALocationManager.m
  39. +52 −0 Classes/Control/OBALogger.h
  40. +47 −0 Classes/Control/OBALogger.m
  41. +48 −0 Classes/Control/OBAModelDAO.h
  42. +224 −0 Classes/Control/OBAModelDAO.m
  43. +27 −0 Classes/Control/OBAModelDAOUserPreferencesImpl.h
  44. +119 −0 Classes/Control/OBAModelDAOUserPreferencesImpl.m
  45. +34 −0 Classes/Control/OBAModelFactory.h
  46. +480 −0 Classes/Control/OBAModelFactory.m
  47. +25 −0 Classes/Control/OBAPredictedArrivalsSource.h
  48. +35 −0 Classes/Control/OBAProgressIndicatorImpl.h
  49. +48 −0 Classes/Control/OBAProgressIndicatorImpl.m
  50. +33 −0 Classes/Control/OBAProgressIndicatorSource.h
  51. +104 −0 Classes/Control/OBASearchController.h
  52. +135 −0 Classes/Control/OBASearchController.m
  53. +52 −0 Classes/Control/OBASearchControllerImpl.h
  54. +651 −0 Classes/Control/OBASearchControllerImpl.m
  55. +26 −0 Classes/Control/OBASphericalGeometryLibrary.h
  56. +37 −0 Classes/Control/OBASphericalGeometryLibrary.m
  57. +57 −0 Classes/Control/OBAStopAndPredictedArrivalsSearch.h
  58. +130 −0 Classes/Control/OBAStopAndPredictedArrivalsSearch.m
  59. +22 −0 Classes/Control/OBAStopSource.h
  60. +25 −0 Classes/Control/OBAStopsSource.h
  61. +40 −0 Classes/Model/OBAAgency.h
  62. +28 −0 Classes/Model/OBAAgency.m
  63. +28 −0 Classes/Model/OBAAgencyWithCoverage.h
  64. +30 −0 Classes/Model/OBAAgencyWithCoverage.m
  65. +47 −0 Classes/Model/OBAArrivalAndDeparture.h
  66. +49 −0 Classes/Model/OBAArrivalAndDeparture.m
  67. +29 −0 Classes/Model/OBAArrivalsAndDeparturesForStop.h
  68. +38 −0 Classes/Model/OBAArrivalsAndDeparturesForStop.m
  69. +36 −0 Classes/Model/OBABookmark.h
  70. +33 −0 Classes/Model/OBABookmark.m
  71. +38 −0 Classes/Model/OBACoordinateBounds.h
  72. +74 −0 Classes/Model/OBACoordinateBounds.m
  73. +31 −0 Classes/Model/OBAGenericAnnotation.h
  74. +53 −0 Classes/Model/OBAGenericAnnotation.m
  75. +45 −0 Classes/Model/OBAModel.h
  76. +28 −0 Classes/Model/OBAModel.m
  77. +34 −0 Classes/Model/OBANavigationTargetAnnotation.h
  78. +46 −0 Classes/Model/OBANavigationTargetAnnotation.m
  79. +31 −0 Classes/Model/OBAPlacemark.h
  80. +63 −0 Classes/Model/OBAPlacemark.m
  81. +48 −0 Classes/Model/OBARoute.h
  82. +45 −0 Classes/Model/OBARoute.m
  83. +66 −0 Classes/Model/OBAStop.h
  84. +88 −0 Classes/Model/OBAStop.m
  85. +35 −0 Classes/Model/OBAStopAccessEvent.h
  86. +33 −0 Classes/Model/OBAStopAccessEvent.m
  87. +29 −0 Classes/Model/OBAStopAnnotation.h
  88. +63 −0 Classes/Model/OBAStopAnnotation.m
  89. +46 −0 Classes/Model/OBAStopPreferences.h
  90. +28 −0 Classes/Model/OBAStopPreferences.m
  91. +61 −0 Classes/OBAApplicationContext.h
  92. +366 −0 Classes/OBAApplicationContext.m
  93. +39 −0 Classes/OBANavigationTarget.h
  94. +79 −0 Classes/OBANavigationTarget.m
  95. +28 −0 Classes/OBANavigationTargetAware.h
  96. +44 −0 Classes/OBAViewContext.h
  97. +149 −0 Classes/OBAViewContext.m
  98. +34 −0 Classes/View/OBAArrivalEntryTableViewCell.h
  99. +64 −0 Classes/View/OBAArrivalEntryTableViewCell.m
  100. +27 −0 Classes/View/OBABookmarksDAO.h
  101. +20 −0 Classes/View/OBABookmarksDAO.m
  102. +30 −0 Classes/View/OBABookmarksViewController.h
  103. +173 −0 Classes/View/OBABookmarksViewController.m
  104. +39 −0 Classes/View/OBAEditStopBookmarkViewController.h
  105. +140 −0 Classes/View/OBAEditStopBookmarkViewController.m
  106. +35 −0 Classes/View/OBAEditStopPreferencesViewController.h
  107. +215 −0 Classes/View/OBAEditStopPreferencesViewController.m
  108. +28 −0 Classes/View/OBANearbyStopsPageTableViewCell.h
  109. +25 −0 Classes/View/OBANearbyStopsPageTableViewCell.m
  110. +37 −0 Classes/View/OBAProgressIndicatorView.h
  111. +108 −0 Classes/View/OBAProgressIndicatorView.m
  112. +28 −0 Classes/View/OBARecentStopsViewController.h
  113. +106 −0 Classes/View/OBARecentStopsViewController.m
  114. +30 −0 Classes/View/OBASearchResultsListViewController.h
  115. +235 −0 Classes/View/OBASearchResultsListViewController.m
  116. +49 −0 Classes/View/OBASearchResultsMapViewController.h
  117. +671 −0 Classes/View/OBASearchResultsMapViewController.m
  118. +30 −0 Classes/View/OBASearchTableViewCell.h
  119. +49 −0 Classes/View/OBASearchTableViewCell.m
  120. +51 −0 Classes/View/OBASearchViewController.h
  121. +215 −0 Classes/View/OBASearchViewController.m
  122. +27 −0 Classes/View/OBASettingsViewController.h
  123. +111 −0 Classes/View/OBASettingsViewController.m
  124. +33 −0 Classes/View/OBAStopTableViewCell.h
  125. +58 −0 Classes/View/OBAStopTableViewCell.m
  126. +49 −0 Classes/View/OBAStopViewController.h
  127. +430 −0 Classes/View/OBAStopViewController.m
  128. +28 −0 Classes/View/OBATextFieldTableViewCell.h
  129. +56 −0 Classes/View/OBATextFieldTableViewCell.m
  130. +40 −0 Classes/View/OBAUIKit.h
  131. +118 −0 Classes/View/OBAUIKit.m
  132. +24 −0 Classes/View/OBAUITableViewCell.h
  133. +49 −0 Classes/View/OBAUITableViewCell.m
  134. +8 −0 Entitlements.plist
  135. +30 −0 Info.plist
  136. +1,066 −0 Resources/AppIcon.ai
  137. BIN Resources/AppIcon.png
  138. +701 −0 Resources/Icons/Bookmarks.ai
  139. BIN Resources/Icons/Bookmarks.png
  140. +691 −0 Resources/Icons/Clock.ai
  141. BIN Resources/Icons/Clock.png
  142. +686 −0 Resources/Icons/CrossHairs.ai
  143. BIN Resources/Icons/CrossHairs.png
  144. +718 −0 Resources/Icons/Gear.ai
  145. BIN Resources/Icons/Gear.png
  146. +708 −0 Resources/Icons/MagnifyingGlass.ai
  147. BIN Resources/Icons/MagnifyingGlass.png
  148. +717 −0 Resources/Icons/SegmentedControl-CrossHairs.ai
  149. BIN Resources/Icons/SegmentedControl-CrossHairs.png
  150. +720 −0 Resources/Icons/SegmentedControl-Region.ai
  151. BIN Resources/Icons/SegmentedControl-Region.png
Sorry, we could not display the entire diff because it was too big.
View
43 Classes/ActivityRecognition/Control/OBAActivityLogger.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBARotatingLogger.h"
+#import "OBAActivityListeners.h"
+#import "OBALocationManager.h"
+
+@class OBAApplicationContext;
+
+@interface OBAActivityLogger : NSObject<OBALocationManagerDelegate,UIAccelerometerDelegate,OBAActivityListener> {
+
+ OBAApplicationContext * _context;
+
+ OBARotatingLogger * _locationLogger;
+ OBARotatingLogger * _accelerometerLogger;
+ OBARotatingLogger * _activityLogger;
+
+ BOOL _running;
+}
+
++ (OBAActivityLogger*) getLogger;
+
+@property (nonatomic,retain) OBAApplicationContext * context;
+
+-(NSArray*) getLogFilePaths;
+
+-(void) start;
+-(void) stop;
+
+@end
View
196 Classes/ActivityRecognition/Control/OBAActivityLogger.m
@@ -0,0 +1,196 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAActivityLogger.h"
+#import "SBJSON.h"
+#import "OBALogger.h"
+#import "OBAApplicationContext.h"
+
+
+static const BOOL kLogAccelerometer = YES;
+
+NSString * const kActivityNameKey = @"name";
+NSString * const kActivityTimeKey = @"time";
+
+static OBAActivityLogger * _staticInstance = nil;
+
+
+@interface OBAActivityLogger (Private)
+
+- (NSMutableDictionary*) getActivityRecord:(NSString*)activityName;
+- (void) writeJSONRecord:(NSDictionary*)dictionary toLogger:(OBARotatingLogger*)logger;
+
+@end
+
+
+@implementation OBAActivityLogger
+
+@synthesize context = _context;
+
+-(id) init {
+ if( self = [super init] ) {
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+
+ NSString * locationPath =[NSString stringWithFormat:@"%@/Location",documentsDirectory];
+ NSString * accelerometerPath =[NSString stringWithFormat:@"%@/Accelerometer",documentsDirectory];
+ NSString * activityPath =[NSString stringWithFormat:@"%@/Activity",documentsDirectory];
+
+ _locationLogger = [[OBARotatingLogger alloc] initWithDirectory:locationPath withMaxFileSize:100*1024];
+ _accelerometerLogger = [[OBARotatingLogger alloc] initWithDirectory:accelerometerPath withMaxFileSize:10*1024*1024];
+ _activityLogger = [[OBARotatingLogger alloc] initWithDirectory:activityPath withMaxFileSize:100*1024];
+
+ _staticInstance = self;
+ _running = NO;
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [self stop];
+ [_context release];
+ [_locationLogger release];
+ [_accelerometerLogger release];
+ [_activityLogger release];
+ [super dealloc];
+}
+
++ (OBAActivityLogger*) getLogger {
+ return _staticInstance;
+}
+
+-(NSArray*) getLogFilePaths {
+ NSMutableArray * logFilePaths = [NSMutableArray arrayWithCapacity:0];
+ [logFilePaths addObjectsFromArray:_locationLogger.individualTracePaths];
+ [logFilePaths addObjectsFromArray:_accelerometerLogger.individualTracePaths];
+ [logFilePaths addObjectsFromArray:_activityLogger.individualTracePaths];
+ return logFilePaths;
+}
+
+-(void) start {
+
+ @synchronized(self) {
+
+ if( _running )
+ return;
+
+ [_locationLogger open];
+ [_accelerometerLogger open];
+ [_activityLogger open];
+
+ [_context.locationManager addDelegate:self];
+
+ if( kLogAccelerometer ) {
+ UIAccelerometer * accel = [UIAccelerometer sharedAccelerometer];
+ [accel setDelegate:self];
+ }
+
+ [_context.activityListeners addListener:self];
+
+ _running = YES;
+ }
+}
+
+-(void) stop {
+
+ @synchronized(self) {
+
+ if( ! _running )
+ return;
+
+ [_context.locationManager removeDelegate:self];
+
+ if( kLogAccelerometer ) {
+ UIAccelerometer * accel = [UIAccelerometer sharedAccelerometer];
+ [accel setDelegate:nil];
+ }
+
+ [_context.activityListeners removeListener:self];
+
+ [_locationLogger close];
+ [_accelerometerLogger close];
+ [_activityLogger close];
+
+ _running = NO;
+ }
+}
+
+- (void)locationManager:(OBALocationManager *)manager didUpdateLocation:(CLLocation *)location {
+ NSDate * timestamp = location.timestamp;
+
+ CLLocationCoordinate2D coord = location.coordinate;
+ NSString * line = [NSString stringWithFormat:@"v1,%f,%f,%f,%f\n",[timestamp timeIntervalSince1970],coord.latitude,coord.longitude,location.horizontalAccuracy];
+ [_locationLogger write:line];
+}
+
+- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {
+ double t = CFAbsoluteTimeGetCurrent();
+ NSString * line = [NSString stringWithFormat:@"v2,%f,%f,%f,%f,%f\n",acceleration.timestamp,t,acceleration.x,acceleration.y,acceleration.z];
+ [_accelerometerLogger write:line];
+}
+
+#pragma mark OBAActivityListener Methods
+
+- (void) bookmarkClicked:(OBABookmark*)bookmark {
+ NSMutableDictionary * dict = [self getActivityRecord:@"bookmarkClicked"];
+ [dict setObject:bookmark.name forKey:@"bookmarkName"];
+ [dict setObject:bookmark.stop.stopId forKey:@"stopId"];
+ [self writeJSONRecord:dict toLogger:_activityLogger];
+}
+
+- (void) viewedArrivalsAndDeparturesForStop:(OBAStop*)stop {
+ NSMutableDictionary * dict = [self getActivityRecord:@"viewArrivalsAndDeparturesForStop"];
+ [dict setObject:stop.stopId forKey:@"stopId"];
+ [self writeJSONRecord:dict toLogger:_activityLogger];
+}
+
+- (void) annotationWithLabel:(NSString*)label {
+ NSMutableDictionary * dict = [self getActivityRecord:@"annotationWithLabel"];
+ [dict setObject:label forKey:@"annotationLabel"];
+ [self writeJSONRecord:dict toLogger:_activityLogger];
+}
+
+@end
+
+@implementation OBAActivityLogger (Private)
+
+- (NSMutableDictionary*) getActivityRecord:(NSString*)activityName {
+
+ NSMutableDictionary * dict = [NSMutableDictionary dictionary];
+ [dict setObject:activityName forKey:kActivityNameKey];
+ NSDate * now = [NSDate date];
+ [dict setObject:[NSNumber numberWithDouble:[now timeIntervalSince1970]] forKey:kActivityTimeKey];
+ return dict;
+}
+
+- (void) writeJSONRecord:(NSDictionary*)dictionary toLogger:(OBARotatingLogger*)logger {
+
+ SBJSON * parser = [[SBJSON alloc] init];
+ NSError * error = nil;
+ NSString * recordAsString = [parser stringWithObject:dictionary error:&error];
+ [parser release];
+
+ if( error ) {
+ OBALogSevereWithError(error,@"Error converting activity record to JSON: record=%@",[dictionary description]);
+ return;
+ }
+
+ NSString * line = [NSString stringWithFormat:@"%@\n",recordAsString];
+ [logger write:line];
+}
+
+@end
View
41 Classes/ActivityRecognition/Control/OBARotatingLogger.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#import <Foundation/Foundation.h>
+
+
+@interface OBARotatingLogger : NSObject {
+ NSString * _path;
+ NSUInteger _maxFileSize;
+
+ NSOutputStream * _currentOutputStream;
+ NSUInteger _currentOutputSize;
+}
+
+@property (nonatomic,readonly) NSString * path;
+@property (nonatomic,readonly) NSArray * individualTracePaths;
+
+-(id) initWithDirectory:(NSString*)path withMaxFileSize:(NSUInteger)size;
+-(void) open;
+-(void) close;
+-(void) write:(NSString*)stringData;
+
+-(BOOL) ensureParentDirectoryExists;
+-(BOOL) ensureCurrentOutput;
+
+
+
+@end
View
128 Classes/ActivityRecognition/Control/OBARotatingLogger.m
@@ -0,0 +1,128 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBARotatingLogger.h"
+
+
+@implementation OBARotatingLogger
+
+@synthesize path = _path;
+
+-(id) initWithDirectory:(NSString*)path withMaxFileSize:(NSUInteger)maxFileSize {
+ if( self = [super init] ) {
+
+ _path = [path retain];
+ _maxFileSize = maxFileSize;
+
+ _currentOutputStream = nil;
+ _currentOutputSize = 0;
+
+ [self ensureParentDirectoryExists];
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [_currentOutputStream release];
+ [super dealloc];
+}
+
+-(NSArray*) individualTracePaths {
+ NSFileManager * manager = [NSFileManager defaultManager];
+ NSMutableArray * paths = [NSMutableArray arrayWithCapacity:0];
+ for( NSString * trace in [manager directoryContentsAtPath:_path] )
+ [paths addObject:[NSString stringWithFormat:@"%@/%@",_path,trace]];
+ return paths;
+}
+
+-(void) open {
+
+}
+
+-(void) close {
+ [_currentOutputStream close];
+ [_currentOutputStream release];
+ _currentOutputStream = nil;
+}
+
+-(void) write:(NSString*)stringData {
+
+ [self ensureCurrentOutput];
+
+ if( _currentOutputStream ) {
+
+ NSData * data = [[stringData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] retain];
+ NSUInteger remaining = [data length];
+
+ while( remaining > 0 ) {
+ NSRange range = NSMakeRange([data length] - remaining, remaining);
+ NSData * sub = [data subdataWithRange:range];
+ NSInteger rc = [_currentOutputStream write:[sub bytes] maxLength:[sub length]];
+ if( rc < 0 )
+ break;
+ remaining -= rc;
+ }
+
+ _currentOutputSize += [data length] - remaining;
+ [data release];
+ }
+}
+
+-(BOOL) ensureParentDirectoryExists {
+
+ NSFileManager * manager = [NSFileManager defaultManager];
+ BOOL isDirectory;
+
+ if( [manager fileExistsAtPath:_path isDirectory:&isDirectory] ) {
+ if( isDirectory )
+ return TRUE;
+ NSLog(@"Target directory already exists as file, will attempt to delete file and create directory: %@",_path);
+
+ NSError * error;
+ if( ! [manager removeItemAtPath:_path error:&error] ) {
+ NSLog(@"Error deleting file: %@ - %@",_path,[error localizedDescription]);
+ return FALSE;
+ }
+ }
+
+ if( [manager createDirectoryAtPath:_path attributes:nil] )
+ return TRUE;
+
+ NSLog(@"Error creating directory: %@",_path);
+ return FALSE;
+}
+
+-(BOOL) ensureCurrentOutput {
+
+ if( ! _currentOutputStream || _currentOutputSize >= _maxFileSize ) {
+
+ [_currentOutputStream close];
+ [_currentOutputStream release];
+ _currentOutputStream = nil;
+
+ NSDate * date = [NSDate date];
+ NSString * currentPath = [NSString stringWithFormat:@"%@/%f.data",_path,[date timeIntervalSince1970]];
+
+ _currentOutputStream = [[NSOutputStream alloc] initToFileAtPath:currentPath append:YES];
+ _currentOutputSize = 0;
+
+ [_currentOutputStream open];
+ }
+
+ return TRUE;
+}
+
+@end
View
53 Classes/ActivityRecognition/Control/OBAUploadManager.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAJsonDataSource.h"
+#import "OBAPredictedArrivalsSource.h"
+#import "OBADataSource.h"
+
+
+@class OBAProgressIndicatorImpl;
+
+@interface OBAUploadManager : NSObject<OBADataSourceDelegate> {
+
+ OBAJsonDataSource * _jsonDataSource;
+
+ NSString * _tracesOnDisk;
+ NSString * _tracesOnServer;
+ NSString * _tracesToUpload;
+
+ NSMutableDictionary * _traceIds;
+ NSMutableSet * _traceIdsOnServer;
+ BOOL _uploading;
+
+ OBAProgressIndicatorImpl * _progress;
+}
+
+@property (nonatomic,retain) OBAJsonDataSource * jsonDataSource;
+
+@property (nonatomic,retain) NSString * tracesOnDisk;
+@property (nonatomic,retain) NSString * tracesOnServer;
+@property (nonatomic,retain) NSString * tracesToUpload;
+
+@property (retain,readonly) NSObject<OBAProgressIndicatorSource>* progress;
+
+-(void) start;
+-(void) stop;
+
+-(void) startUploading;
+-(void) stopUploading;
+
+@end
View
203 Classes/ActivityRecognition/Control/OBAUploadManager.m
@@ -0,0 +1,203 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBACommon.h"
+#import "OBAUploadManager.h"
+#import "OBAActivityLogger.h"
+#import "OBAProgressIndicatorImpl.h"
+
+
+@interface OBAUploadManager(InternalMethods)
+- (void) updateServerStatus;
+- (void) handleServerStatus:(NSDictionary*)dict;
+- (void) uploadNextTrace;
+@end
+
+
+
+@implementation OBAUploadManager
+
+@synthesize jsonDataSource = _jsonDataSource;
+
+@synthesize tracesOnDisk = _tracesOnDisk;
+@synthesize tracesOnServer = _tracesOnServer;
+@synthesize tracesToUpload = _tracesToUpload;
+
+@synthesize progress = _progress;
+
+-(id) init {
+ if( self = [super init]) {
+ _traceIds = [[NSMutableDictionary alloc] init];
+ _traceIdsOnServer = [[NSMutableSet alloc] init];
+ _uploading = NO;
+ _progress = [[OBAProgressIndicatorImpl alloc] init];
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [_jsonDataSource release];
+
+ [_traceIds release];
+ [_traceIdsOnServer release];
+
+ [_tracesOnDisk release];
+ [_tracesOnServer release];
+ [_tracesToUpload release];
+
+ [_progress release];
+
+ [super dealloc];
+}
+
+-(void) start {
+
+ OBAActivityLogger * logger = [OBAActivityLogger getLogger];
+ [logger stop];
+
+ NSArray * paths = [logger getLogFilePaths];
+
+ [_traceIds removeAllObjects];
+
+ float totalFileSize = 0;
+ UIDevice * device = [UIDevice currentDevice];
+ NSFileManager * fileManager = [NSFileManager defaultManager];
+
+ for( NSString * path in paths ) {
+
+ NSArray * components = [path componentsSeparatedByString:@"/"];
+ NSUInteger n = [components count];
+
+ if( n >= 2 ) {
+
+ NSString * traceId = [NSString stringWithFormat:@"%@-%@-%@",device.uniqueIdentifier,[components objectAtIndex:n-2],[components objectAtIndex:n-1]];
+ [_traceIds setObject:path forKey:traceId];
+
+ NSDictionary *fileAttributes = [fileManager fileAttributesAtPath:path traverseLink:YES];
+ if( fileAttributes ) {
+ NSNumber *fileSize = [fileAttributes objectForKey:NSFileSize];
+ if( fileSize )
+ totalFileSize += [fileSize floatValue];
+ }
+ }
+ }
+
+ NSString * label = @"bytes";
+
+ if( totalFileSize >= 1024) {
+ totalFileSize /= 1024;
+ label = @"KB";
+ }
+
+ if( totalFileSize >= 1024) {
+ totalFileSize /= 1024;
+ label = @"MB";
+ }
+
+ self.tracesOnDisk = [NSString stringWithFormat:@"%d - %0.1f %@",[_traceIds count],totalFileSize,label];
+
+ [self updateServerStatus];
+}
+
+-(void) stop {
+ OBAActivityLogger * logger = [OBAActivityLogger getLogger];
+ [logger start];
+}
+
+- (void)connectionDidFinishLoading:(id<OBADataSourceConnection>)connection withObject:(id) obj context:(id)context{
+
+ if( [@"upload" isEqual:context] ) {
+ [self uploadNextTrace];
+ }
+ else if( [@"checkServer" isEqual:context] ) {
+ [self handleServerStatus:obj];
+ }
+}
+
+- (void)connection:(id<OBADataSourceConnection>)connection withProgress:(float)progress {
+ [_progress setInProgress:TRUE progress:progress];
+}
+
+- (void)connectionDidFail:(id<OBADataSourceConnection>)connection withError:(NSError *)error context:(id)context{
+ NSLog(@"connection error: %@",[error localizedDescription]);
+ [_progress setMessage:@"Error connecting" inProgress:FALSE progress:0];
+}
+
+-(void) startUploading {
+ _uploading = YES;
+ [self uploadNextTrace];
+}
+
+-(void) stopUploading {
+
+}
+
+@end
+
+@implementation OBAUploadManager(InternalMethods)
+
+-(void) updateServerStatus {
+ [_progress setMessage:@"Connecting..." inProgress:TRUE progress:0];
+ [_jsonDataSource requestWithPath:@"/api/datacollection/existing-data.json" withDelegate:self context:@"checkServer"];
+}
+
+
+- (void) handleServerStatus:(NSDictionary*)dict {
+ NSNumber * code = [dict objectForKey:@"code"];
+ if( code && [code intValue] == 200) {
+ NSArray * data = [dict objectForKey:@"data"];
+ NSUInteger onServer = 0;
+ [_traceIdsOnServer removeAllObjects];
+ for( NSString * traceId in data ) {
+ if( [_traceIds objectForKey:traceId] ) {
+ onServer++;
+ [_traceIdsOnServer addObject:traceId];
+ }
+ }
+
+ self.tracesOnServer = [NSString stringWithFormat:@"%d",onServer];
+ self.tracesToUpload = [NSString stringWithFormat:@"%d",[_traceIds count]-onServer];
+
+ NSString * message = [NSString stringWithFormat:@"Updated: %@", [OBACommon getTimeAsString]];
+ [_progress setMessage:message inProgress:FALSE progress:0];
+ }
+
+}
+
+-(void) uploadNextTrace {
+ if( [_traceIds count] > 0 ) {
+
+ self.tracesOnServer = [NSString stringWithFormat:@"%d",[_traceIdsOnServer count]];
+
+ NSArray * keys = [_traceIds allKeys];
+ for( NSString * traceId in keys ) {
+ if( [_traceIdsOnServer containsObject:traceId] )
+ continue;
+ [_traceIdsOnServer addObject:traceId];
+
+ NSString * url = [NSString stringWithFormat:@"/api/datacollection/upload-data/%@/update",traceId];
+ NSString * filePath = [_traceIds objectForKey:traceId];
+
+ [_progress setMessage:@"Uploading..." inProgress:TRUE progress:0];
+ [_jsonDataSource requestWithPath:url withArgs:nil withFileUpload:filePath withDelegate:self context:@"upload"];
+ return;
+ }
+ }
+ _uploading = NO;
+ [self updateServerStatus];
+}
+
+@end
View
29 Classes/ActivityRecognition/View/OBAActivityAnnotationViewController.h
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#import <UIKit/UIKit.h>
+#import "OBAApplicationContext.h"
+#import "OBANavigationTargetAware.h"
+
+@interface OBAActivityAnnotationViewController : UITableViewController <OBANavigationTargetAware> {
+ OBAApplicationContext * _appContext;
+ NSDictionary * _actionLabels;
+ NSArray * _actionKeys;
+}
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext;
+
+@end
View
91 Classes/ActivityRecognition/View/OBAActivityAnnotationViewController.m
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAActivityAnnotationViewController.h"
+#import "OBAUITableViewCell.h"
+
+
+@implementation OBAActivityAnnotationViewController
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext {
+ if( self = [super initWithStyle:UITableViewStyleGrouped] ) {
+ _appContext = [appContext retain];
+
+ _actionKeys = [[NSArray alloc] initWithObjects:@"stopped",@"walk",@"bike",@"car",@"bus",@"train",@"waiting",nil];
+
+ NSMutableDictionary * actions = [[NSMutableDictionary alloc] init];
+
+ [actions setObject:@"Stopped" forKey:@"stopped"];
+ [actions setObject:@"Walking" forKey:@"walk"];
+ [actions setObject:@"Bicycling" forKey:@"bike"];
+ [actions setObject:@"In a Car" forKey:@"car"];
+ [actions setObject:@"On a Bus" forKey:@"bus"];
+ [actions setObject:@"On a Train" forKey:@"train"];
+ [actions setObject:@"Waiting" forKey:@"waiting"];
+
+ _actionLabels = [actions retain];
+
+ [actions release];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_appContext release];
+ [_actionKeys release];
+ [_actionLabels release];
+ [super dealloc];
+}
+
+#pragma mark Table view methods
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+
+// Customize the number of rows in the table view.
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [_actionKeys count];
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ NSString * actionKey = [_actionKeys objectAtIndex:indexPath.row];
+ NSString * actionLabel = [_actionLabels objectForKey:actionKey];
+
+ UITableViewCell * cell = [UITableViewCell getOrCreateCellForTableView:tableView];
+ cell.textLabel.text = actionLabel;
+ return cell;
+}
+
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSString * actionKey = [_actionKeys objectAtIndex:indexPath.row];
+ [_appContext.activityListeners annotationWithLabel:actionKey];
+ [self.navigationController popViewControllerAnimated:TRUE];
+}
+
+#pragma mark OBANavigationTargetAware
+
+- (OBANavigationTarget*) navigationTarget {
+ return [OBANavigationTarget target:OBANavigationTargetTypeActivityAnnotation];
+}
+
+@end
+
View
28 Classes/ActivityRecognition/View/OBAActivityLoggingViewController.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#import <UIKit/UIKit.h>
+#import "OBAApplicationContext.h"
+#import "OBANavigationTargetAware.h"
+
+
+@interface OBAActivityLoggingViewController : UITableViewController <OBANavigationTargetAware> {
+ OBAApplicationContext * _appContext;
+}
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext;
+
+@end
View
102 Classes/ActivityRecognition/View/OBAActivityLoggingViewController.m
@@ -0,0 +1,102 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAActivityLoggingViewController.h"
+#import "OBAUITableViewCell.h"
+#import "OBAActivityAnnotationViewController.h"
+#import "OBAUploadViewController.h"
+#import "OBALockViewController.h"
+
+
+@implementation OBAActivityLoggingViewController
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext {
+ if( self = [super initWithStyle:UITableViewStyleGrouped] ) {
+ _appContext = [appContext retain];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_appContext release];
+ [super dealloc];
+}
+
+
+#pragma mark Table view methods
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+
+// Customize the number of rows in the table view.
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return 3;
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ UITableViewCell * cell = [UITableViewCell getOrCreateCellForTableView:tableView];
+ switch(indexPath.row) {
+ case 0:
+ cell.textLabel.text = @"Annotate Activity";
+ break;
+ case 1:
+ cell.textLabel.text = @"Upload Data";
+ break;
+ case 2:
+ cell.textLabel.text = @"Lock Screen";
+ break;
+ }
+
+ return cell;
+}
+
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ UINavigationController * vc = nil;
+
+ switch (indexPath.row) {
+ case 0:
+ vc = [[OBAActivityAnnotationViewController alloc] initWithApplicationContext:_appContext];
+ break;
+ case 1:
+ vc = [[OBAUploadViewController alloc] initWithApplicationContext:_appContext];
+ break;
+ case 2:
+ vc = [[OBALockViewController alloc] initWithApplicationContext:_appContext];
+ break;
+ default:
+ vc = [[OBAActivityAnnotationViewController alloc] initWithApplicationContext:_appContext];
+ break;
+ }
+
+ [self.navigationController pushViewController:vc animated:TRUE];
+ [vc release];
+}
+
+#pragma mark OBANavigationTargetAware
+
+- (OBANavigationTarget*) navigationTarget {
+ return [OBANavigationTarget target:OBANavigationTargetTypeActivityLogging];
+}
+
+@end
+
View
58 Classes/ActivityRecognition/View/OBALockViewController.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#import <UIKit/UIKit.h>
+#import "OBAApplicationContext.h"
+#import "OBANavigationTargetAware.h"
+
+
+@interface OBALockViewController : UIViewController <OBANavigationTargetAware> {
+
+ OBAApplicationContext * _appContext;
+
+ NSArray * _key;
+ int _keyIndex;
+
+ NSTimer * _timer;
+
+ UIButton * _button0;
+ UIButton * _button1;
+ UIButton * _button2;
+ UIButton * _button3;
+ UIButton * _button4;
+ UIButton * _button5;
+ UIButton * _button6;
+ UIButton * _button7;
+ UIButton * _button8;
+ UIButton * _button9;
+}
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext;
+
+@property (nonatomic,retain) IBOutlet UIButton * button0;
+@property (nonatomic,retain) IBOutlet UIButton * button1;
+@property (nonatomic,retain) IBOutlet UIButton * button2;
+@property (nonatomic,retain) IBOutlet UIButton * button3;
+@property (nonatomic,retain) IBOutlet UIButton * button4;
+@property (nonatomic,retain) IBOutlet UIButton * button5;
+@property (nonatomic,retain) IBOutlet UIButton * button6;
+@property (nonatomic,retain) IBOutlet UIButton * button7;
+@property (nonatomic,retain) IBOutlet UIButton * button8;
+@property (nonatomic,retain) IBOutlet UIButton * button9;
+
+-(IBAction) onButtonClick:(id)source;
+
+@end
View
204 Classes/ActivityRecognition/View/OBALockViewController.m
@@ -0,0 +1,204 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBALockViewController.h"
+
+static const int kKeyLength = 4;
+static const double kKeyTimeout = 3.0;
+
+@interface OBALockViewController(Private)
+
+-(void) refreshButtons;
+-(UIButton*) getButtonForIndex:(int)index;
+
+@end
+
+
+@implementation OBALockViewController
+
+@synthesize button0 = _button0;
+@synthesize button1 = _button1;
+@synthesize button2 = _button2;
+@synthesize button3 = _button3;
+@synthesize button4 = _button4;
+@synthesize button5 = _button5;
+@synthesize button6 = _button6;
+@synthesize button7 = _button7;
+@synthesize button8 = _button8;
+@synthesize button9 = _button9;
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext {
+ if (self = [super initWithNibName:@"OBALockView" bundle:nil]) {
+ self.hidesBottomBarWhenPushed = TRUE;
+ self.navigationItem.title = @"Lock Screen";
+ self.navigationItem.hidesBackButton = TRUE;
+ _appContext = [appContext retain];
+ }
+ return self;
+}
+
+
+- (void)dealloc {
+ [_appContext release];
+ [_key release];
+ [_timer release];
+ [super dealloc];
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+
+ [_appContext.activityListeners annotationWithLabel:@"lockOn"];
+
+ UIApplication * application = [UIApplication sharedApplication];
+ application.idleTimerDisabled = TRUE;
+
+ NSMutableArray * key = [[NSMutableArray alloc] initWithCapacity:kKeyLength];
+
+ for( int i=0; i<kKeyLength;i++) {
+
+ while(TRUE) {
+
+ int keyDigit = arc4random() % 10;
+
+ // No sequential duplicates
+ if( i > 0 ) {
+ NSNumber * prev = [key objectAtIndex:i-1];
+ if( [prev intValue] == keyDigit )
+ continue;
+ }
+
+ NSNumber * n = [NSNumber numberWithInt: keyDigit];
+ [key addObject:n];
+ break;
+ }
+ }
+ _key = key;
+ _keyIndex = 0;
+
+ [self refreshButtons];
+}
+
+- (void)viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+
+ UIApplication * application = [UIApplication sharedApplication];
+ application.idleTimerDisabled = FALSE;
+}
+
+
+
+- (void) timerFireMethod:(NSTimer*)theTimer {
+ @synchronized(self) {
+ _keyIndex = 0;
+ [self refreshButtons];
+ }
+}
+
+-(IBAction) onButtonClick:(id)source {
+
+ @synchronized(self) {
+ UIButton * button = source;
+ int index = [button.titleLabel.text intValue];
+
+ NSNumber * target = [_key objectAtIndex:_keyIndex];
+
+ if( _timer ) {
+ [_timer invalidate];
+ [_timer release];
+ _timer = nil;
+ }
+
+ if( [target intValue] == index ) {
+ _keyIndex++;
+ if( _keyIndex == [_key count] ) {
+ [_appContext.activityListeners annotationWithLabel:@"lockOff"];
+ [self.navigationController popViewControllerAnimated:TRUE];
+ return;
+ }
+ [self refreshButtons];
+ }
+ else {
+ _keyIndex = 0;
+ [self refreshButtons];
+ }
+ }
+}
+
+#pragma mark OBANavigationTargetAware
+
+- (OBANavigationTarget*) navigationTarget {
+ return [OBANavigationTarget target:OBANavigationTargetTypeActivityLock];
+}
+
+@end
+
+@implementation OBALockViewController(Private)
+
+-(void) refreshButtons {
+
+ int highlightedButton = -1;
+
+ if( _keyIndex < [_key count] ) {
+ NSNumber * num = [_key objectAtIndex:_keyIndex];
+ highlightedButton = [num intValue];
+ }
+
+ for( int i=0; i<10; i++) {
+ UIButton * button = [self getButtonForIndex:i];
+ UIColor * color = (i == highlightedButton ) ? [UIColor greenColor] : [UIColor blackColor];
+ button.titleLabel.textColor = color;
+ }
+
+ if( _timer ) {
+ [_timer invalidate];
+ [_timer release];
+ }
+
+ _timer = [NSTimer scheduledTimerWithTimeInterval:kKeyTimeout target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:FALSE];
+ [_timer retain];
+}
+
+-(UIButton*) getButtonForIndex:(int)index {
+ switch (index) {
+ case 0:
+ return _button0;
+ case 1:
+ return _button1;
+ case 2:
+ return _button2;
+ case 3:
+ return _button3;
+ case 4:
+ return _button4;
+ case 5:
+ return _button5;
+ case 6:
+ return _button6;
+ case 7:
+ return _button7;
+ case 8:
+ return _button8;
+ case 9:
+ return _button9;
+ default:
+ return nil;
+ }
+
+ return nil;
+}
+
+
+@end
View
38 Classes/ActivityRecognition/View/OBAUploadViewController.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAApplicationContext.h"
+#import "OBANavigationTargetAware.h"
+#import "OBAUploadManager.h"
+
+@interface OBAUploadViewController : UIViewController <OBANavigationTargetAware> {
+
+ OBAUploadManager * _uploadManager;
+
+ UILabel * _tracesOnDiskLabel;
+ UILabel * _tracesOnServerLabel;
+ UILabel * _tracesToUploadLabel;
+}
+
+@property (nonatomic,retain) IBOutlet UILabel * tracesOnDiskLabel;
+@property (nonatomic,retain) IBOutlet UILabel * tracesOnServerLabel;
+@property (nonatomic,retain) IBOutlet UILabel * tracesToUploadLabel;
+
+-(id) initWithApplicationContext:(OBAApplicationContext*)appContext;
+
+-(IBAction)onUploadButton:(id)source;
+
+@end
View
127 Classes/ActivityRecognition/View/OBAUploadViewController.m
@@ -0,0 +1,127 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAUploadManager.h"
+#import "OBAUploadViewController.h"
+#import "OBAProgressIndicatorView.h"
+
+
+@implementation OBAUploadViewController
+
+@synthesize tracesOnDiskLabel = _tracesOnDiskLabel;
+@synthesize tracesOnServerLabel = _tracesOnServerLabel;
+@synthesize tracesToUploadLabel = _tracesToUploadLabel;
+
+- (id) initWithApplicationContext:(OBAApplicationContext*)appContext {
+ if( self = [super initWithNibName:@"OBAUploadView" bundle:[NSBundle mainBundle]] ) {
+ _uploadManager = [[OBAUploadManager alloc] init];
+ _uploadManager.jsonDataSource = [[OBAJsonDataSource alloc] initWithConfig:appContext.obaDataSourceConfig];
+
+ NSMutableArray * items = [[NSMutableArray alloc] init];
+
+ UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:@selector(onAddBookmarkButton:)];
+ [items addObject:spaceItem];
+ [spaceItem release];
+
+ OBAProgressIndicatorView * view = [OBAProgressIndicatorView viewFromNibWithSource:_uploadManager.progress];
+ UIBarButtonItem * progressItem = [[UIBarButtonItem alloc] initWithCustomView:view];
+ [items addObject:progressItem];
+ [progressItem release];
+
+ spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:@selector(onAddBookmarkButton:)];
+ [items addObject:spaceItem];
+ [spaceItem release];
+
+ self.toolbarItems = items;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_uploadManager release];
+ [super dealloc];
+}
+
+
+/*
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView {
+}
+*/
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ [_uploadManager addObserver:self forKeyPath:@"tracesOnDisk" options:NSKeyValueObservingOptionNew context:nil];
+ [_uploadManager addObserver:self forKeyPath:@"tracesOnServer" options:NSKeyValueObservingOptionNew context:nil];
+ [_uploadManager addObserver:self forKeyPath:@"tracesToUpload" options:NSKeyValueObservingOptionNew context:nil];
+
+ [_uploadManager start];
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+
+ [_uploadManager removeObserver:self forKeyPath:@"tracesOnDisk"];
+ [_uploadManager removeObserver:self forKeyPath:@"tracesOnServer"];
+ [_uploadManager removeObserver:self forKeyPath:@"tracesToUpload"];
+
+ [_uploadManager stop];
+}
+
+
+
+/*
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ // Return YES for supported orientations
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+}
+*/
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
+ // Release anything that's not essential, such as cached data
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context {
+
+ if ([keyPath isEqual:@"tracesOnDisk"]) {
+ _tracesOnDiskLabel.text = _uploadManager.tracesOnDisk;
+ }
+ else if ([keyPath isEqual:@"tracesOnServer"]) {
+ _tracesOnServerLabel.text = _uploadManager.tracesOnServer;
+ }
+ else if ([keyPath isEqual:@"tracesToUpload"]) {
+ _tracesToUploadLabel.text = _uploadManager.tracesToUpload;
+ }
+}
+
+-(IBAction)onUploadButton:(id)source {
+ [_uploadManager startUploading];
+}
+
+#pragma mark OBANavigationTargetAware
+
+- (OBANavigationTarget*) navigationTarget {
+ return [OBANavigationTarget target:OBANavigationTargetTypeActivityUpload];
+}
+
+@end
View
26 Classes/Control/DataSource/OBADataSource.h
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@protocol OBADataSourceConnection
+- (void) cancel;
+@end
+
+@protocol OBADataSourceDelegate
+- (void)connectionDidFinishLoading:(id<OBADataSourceConnection>)connection withObject:(id)obj context:(id)context;
+- (void)connectionDidFail:(id<OBADataSourceConnection>)connection withError:(NSError *)error context:(id)context;
+@optional
+- (void)connection:(id<OBADataSourceConnection>)connection withProgress:(float)progress;
+@end
View
30 Classes/Control/DataSource/OBADataSourceConfig.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+@interface OBADataSourceConfig : NSObject {
+ NSString * _url;
+ NSString * _args;
+}
+
+@property (nonatomic,readonly) NSString * url;
+@property (nonatomic,readonly) NSString * args;
+
+- (id) initWithUrl:(NSString*)url args:(NSString*)args;
+
+-(NSURL*) constructURL:(NSString*)path withArgs:(NSString*)args;
+
+@end
View
61 Classes/Control/DataSource/OBADataSourceConfig.m
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBADataSourceConfig.h"
+
+
+@implementation OBADataSourceConfig
+
+@synthesize url = _url;
+@synthesize args = _args;
+
+- (id) initWithUrl:(NSString*)url args:(NSString*)args {
+ if( self = [super init] ) {
+ _url = [url retain];
+ _args = [args retain];
+ }
+ return self;
+}
+
+- (void) dealloc {
+ [_url release];
+ [_args release];
+ [super dealloc];
+}
+
+-(NSURL*) constructURL:(NSString*)path withArgs:(NSString*)args {
+
+ NSMutableString *url = [NSMutableString string];
+ if( _url )
+ [url appendString: _url];
+ [url appendString:path];
+ if( args || _args ) {
+ [url appendString:@"?"];
+ if( _args )
+ [url appendString:_args];
+ if( args ) {
+ if( _args )
+ [url appendString:@"&"];
+ [url appendString:args];
+ }
+ }
+
+ NSLog(@"url=%@",url);
+
+ return [NSURL URLWithString:url];
+}
+
+@end
View
34 Classes/Control/DataSource/OBAJsonDataSource.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBADataSource.h"
+#import "OBADataSourceConfig.h"
+
+
+@interface OBAJsonDataSource : NSObject {
+ OBADataSourceConfig * _config;
+ NSMutableArray * _openConnections;
+}
+
+- (id) initWithConfig:(OBADataSourceConfig*)config;
+
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)path withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context;
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)path withArgs:(NSString*)args withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context;
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)path withArgs:(NSString*)args withFileUpload:(NSString*)filePath withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context;
+
+- (void) cancelOpenConnections;
+
+@end
View
275 Classes/Control/DataSource/OBAJsonDataSource.m
@@ -0,0 +1,275 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAJsonDataSource.h"
+#import "SBJSON.h"
+
+/****
+ * Internal JsonUrlFetcher class that we pass on to our NSURLConnection
+ ****/
+
+@interface JsonUrlFetcherImpl : NSObject <OBADataSourceConnection> {
+ OBAJsonDataSource * _source;
+ NSURLConnection * _connection;
+ NSStringEncoding _responseEncoding;
+ NSMutableData * _jsonData;
+ NSInteger _expectedLength;
+ id<OBADataSourceDelegate> _delegate;
+ id _context;
+ BOOL _uploading;
+ BOOL _canceled;
+}
+
+@property (nonatomic) BOOL uploading;
+
+- (id) initWithSource:(OBAJsonDataSource*)source withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context;
+
+@end
+
+@interface OBAJsonDataSource (Private)
+
+-(void) removeOpenConnection:(JsonUrlFetcherImpl*)connection;
+
+@end
+
+
+
+@implementation OBAJsonDataSource
+
+- (id) initWithConfig:(OBADataSourceConfig*)config {
+ if( self = [super init] ) {
+ _config = [config retain];
+ _openConnections = [[NSMutableArray alloc] init];
+ }
+ return self;
+}
+
+- (void) dealloc {
+ [self cancelOpenConnections];
+ [_config release];
+ [_openConnections release];
+ [super dealloc];
+}
+
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)path withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context {
+ return [self requestWithPath:path withArgs:nil withDelegate:delegate context: context];
+}
+
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)path withArgs:(NSString*)args withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context {
+
+ NSURL *feedURL = [_config constructURL:path withArgs:args];
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:feedURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 20];
+ [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
+ JsonUrlFetcherImpl * fetcher = [[JsonUrlFetcherImpl alloc] initWithSource:self withDelegate:delegate context:context];
+ @synchronized(self) {
+ [_openConnections addObject:fetcher];
+ [NSURLConnection connectionWithRequest:request delegate:fetcher ];
+ }
+
+ return fetcher;
+}
+
+- (id<OBADataSourceConnection>) requestWithPath:(NSString*)url withArgs:(NSString*)args withFileUpload:(NSString*)path withDelegate:(NSObject<OBADataSourceDelegate>*)delegate context:(id)context {
+
+ NSURL *targetUrl = [_config constructURL:url withArgs:args];
+ NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:targetUrl];
+ //[postRequest setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
+
+ //adding header information:
+ [postRequest setHTTPMethod:@"POST"];
+
+ NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
+ NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
+ [postRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
+
+ //setting up the body:
+ NSMutableData *postBody = [NSMutableData data];
+ [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"upload\"; filename=\"upload\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [postBody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+ NSData * fileData = [NSData dataWithContentsOfFile:path];
+ [postBody appendData:fileData];
+ [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [postRequest setHTTPBody:postBody];
+
+ JsonUrlFetcherImpl * fetcher = [[JsonUrlFetcherImpl alloc] initWithSource:self withDelegate:delegate context:context];
+ fetcher.uploading = TRUE;
+ @synchronized(self) {
+ [_openConnections addObject:fetcher];
+ [NSURLConnection connectionWithRequest:postRequest delegate:fetcher ];
+ }
+
+ return fetcher;
+}
+
+- (void) cancelOpenConnections {
+ @synchronized(self) {
+ NSLog(@"Canceling open connections in OBAJSONDataSource");
+ for( JsonUrlFetcherImpl * connection in _openConnections ) {
+ NSLog(@" Canceling open connection in OBAJSONDataSource");
+ [connection cancel];
+ }
+ [_openConnections removeAllObjects];
+ }
+}
+
+@end
+
+@implementation OBAJsonDataSource (Private)
+
+-(void) removeOpenConnection:(JsonUrlFetcherImpl*)connection {
+ @synchronized(self) {
+ [_openConnections removeObject:connection];
+ }
+}
+
+@end
+
+
+
+
+@implementation JsonUrlFetcherImpl
+
+@synthesize uploading = _uploading;
+
+- (id) initWithSource:(OBAJsonDataSource*)source withDelegate:(id<OBADataSourceDelegate>)delegate context:(id)context {
+
+ if( self = [super init]) {
+
+ _source = [source retain];
+ _delegate = delegate;
+ _context = [context retain];
+
+ _jsonData = [[NSMutableData alloc] initWithCapacity:0];
+ _uploading = FALSE;
+ _canceled = FALSE;
+
+ }
+ return self;
+}
+
+- (void) dealloc {
+
+ [_source release];
+ [_context release];
+ [_jsonData release];
+
+ [super dealloc];
+}
+
+- (void) cancel {
+ @synchronized(self) {
+ NSLog(@" Canceling open connection in URL Fetcher");
+ if( _canceled )
+ return;
+ _canceled = TRUE;
+ [_connection cancel];
+ _delegate = nil;
+ [self autorelease];
+ }
+}
+
+#pragma mark NSURLConnection Delegate Methods
+
+- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
+ @synchronized(self) {
+ if( _canceled )
+ return;
+ if( _uploading && [((NSObject*)_delegate) respondsToSelector:@selector(connection:withProgress:)]) {
+ float progress = ((float)totalBytesWritten)/totalBytesExpectedToWrite;
+ [_delegate connection:self withProgress:progress];
+ }
+ }
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
+ @synchronized(self) {
+ if( _canceled )
+ return;
+
+ NSLog(@"Response: length=%lld mime=%@",[response expectedContentLength],[response MIMEType]);
+
+ NSString * textEncodingName = [response textEncodingName];
+ if( textEncodingName )
+ _responseEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)textEncodingName));
+ else
+ _responseEncoding = NSUTF8StringEncoding;
+ _expectedLength = [response expectedContentLength];
+ [_jsonData setLength:0];
+ }
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSMutableData *)data {
+ @synchronized(self) {
+ if( _canceled )
+ return;
+ [_jsonData appendData:data];
+ if( [((NSObject*)_delegate) respondsToSelector:@selector(connection:withProgress:)] ) {
+ float progress = 0;
+ if( _expectedLength > 0 )
+ progress = ((float) [_jsonData length]) / _expectedLength;
+ [_delegate connection:self withProgress:progress];
+ }
+ }
+}
+
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
+
+ @synchronized(self) {
+
+ if( _canceled )
+ return;
+ _canceled = TRUE;
+
+ NSString * v = [[NSString alloc] initWithData:_jsonData encoding:_responseEncoding];
+ SBJSON * parser = [[SBJSON alloc] init];
+ NSError * error = nil;
+ id jsonObject = nil;
+
+ if( v && [v length] > 0 )
+ jsonObject = [parser objectWithString:v error:&error];
+
+ if( error)
+ [_delegate connectionDidFail:self withError:error context:_context];
+ else
+ [_delegate connectionDidFinishLoading:self withObject:jsonObject context:_context];
+
+ [v release];
+ [parser release];
+
+ [_source removeOpenConnection:self];
+ _delegate = nil;
+ [self autorelease];
+ }
+}
+
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
+
+ @synchronized(self) {
+
+ if( _canceled )
+ return;
+ _canceled = TRUE;
+
+ NSLog(@"Connection failed! Error - %@ %@", [error localizedDescription],[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
+ [_delegate connectionDidFail:self withError:error context:_context];
+ [_source removeOpenConnection:self];
+ _delegate = nil;
+ [self autorelease];
+ }
+}
+
+@end
View
28 Classes/Control/Digester/OBACreateManagedEntityJsonDigesterRule.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAJsonDigester.h"
+
+
+@interface OBACreateManagedEntityJsonDigesterRule : NSObject <OBAJsonDigesterRule> {
+ NSString * _entityName;
+ NSString * _entityIdProperty;
+ NSString * _jsonIdProperty;
+}
+
+- (id) initWithEntityName:(NSString*)entityName entityIdProperty:(NSString*)entityIdProperty jsonIdProperty:(NSString*)jsonIdProperty;
+
+@end
View
165 Classes/Control/Digester/OBACreateManagedEntityJsonDigesterRule.m
@@ -0,0 +1,165 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBACreateManagedEntityJsonDigesterRule.h"
+#import "OBACommon.h"
+#import "OBALogger.h"
+
+
+@interface OBACreateManagedEntityJsonDigesterRule (Private)
+
+- (id) getEntityWithEntityId:(id)entityId fromContext:(id<OBAJsonDigesterContext>)context error:(NSError**)error;
+- (NSManagedObjectID*) getManagedObjectIdForEntityWithId:(NSString*)entityId withContext:(id<OBAJsonDigesterContext>)context;
+- (void) setManagedObjectIdForEntityWithId:(NSString*)entityId managedObjectId:(NSManagedObjectID*)managedObjectId context:(id<OBAJsonDigesterContext>)context;
+- (NSMutableDictionary*) getEntityIdMappings:(id<OBAJsonDigesterContext>)context;
+
+@end
+
+
+@implementation OBACreateManagedEntityJsonDigesterRule
+
+- (id) initWithEntityName:(NSString*)entityName entityIdProperty:(NSString*)entityIdProperty jsonIdProperty:(NSString*)jsonIdProperty {
+ if( self = [super init] ) {
+ _entityName = [entityName retain];
+ _entityIdProperty = [entityIdProperty retain];
+ _jsonIdProperty = [jsonIdProperty retain];
+ }
+ return self;
+}
+
+- (void) dealloc {
+ [_entityName release];
+ [_entityIdProperty release];
+ [_jsonIdProperty release];
+ [super dealloc];
+}
+
+#pragma mark OBAJsonDigesterRule Methods
+
+- (void) begin:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value {
+
+ if( ! [value isKindOfClass:[NSDictionary class]] ) {
+ context.error = [NSError errorWithDomain:OBAErrorDomain code:kOBAErrorMissingFieldInData userInfo:nil];
+ return;
+ }
+
+ NSDictionary * dict = value;
+ id entityId = [dict objectForKey:_jsonIdProperty];
+
+ if( entityId == nil ) {
+ context.error = [NSError errorWithDomain:OBAErrorDomain code:kOBAErrorMissingFieldInData userInfo:nil];
+ return;
+ }
+
+ NSError * error = nil;
+ id obj = [self getEntityWithEntityId:entityId fromContext:context error:&error];
+ if( error ) {
+ context.error = error;
+ return;
+ }
+
+ [context pushValue:obj];
+}
+
+- (void) end:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value {
+ [context popValue];
+}
+
+@end
+
+@implementation OBACreateManagedEntityJsonDigesterRule (Private)
+
+- (id) getEntityWithEntityId:(id)entityId fromContext:(id<OBAJsonDigesterContext>)context error:(NSError**)error {
+
+ NSManagedObjectContext * managedObjectContext = [context getParameterForKey:@"managedObjectContext"];
+ NSManagedObjectID * managedObjectId = [self getManagedObjectIdForEntityWithId:entityId withContext:context];
+
+ if( managedObjectId != nil ) {
+ NSError * error = nil;
+ NSManagedObject * obj = [managedObjectContext existingObjectWithID:managedObjectId error:&error];
+ if( error ) {
+ NSString * uri = [[managedObjectId URIRepresentation] absoluteString];
+ OBALogSevereWithError(error,@"Error retrievingExistingObjectWithID: entityName=%@ entityId=%@ managedId=%@",_entityName,entityId,uri);
+ }
+ else {
+ if( [entityId isEqual:[obj valueForKey:_entityIdProperty]] )
+ return obj;
+ NSString * uri = [[managedObjectId URIRepresentation] absoluteString];
+ OBALogWarning(@"Entity id mismatch: entityName=%@ entityId=%@ managedId=%@",_entityName,entityId,uri);
+ }
+ }
+
+ NSEntityDescription *entityDescription = [NSEntityDescription
+ entityForName:_entityName inManagedObjectContext:managedObjectContext];
+
+ NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
+ [request setEntity:entityDescription];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", _entityIdProperty, entityId];
+ [request setPredicate:predicate];
+
+ NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:error];
+
+ if (fetchedObjects == nil) {
+ OBALogSevereWithError((*error),@"Error fetching entity: name=%@ idProperty=%@ id=%@",_entityName,_entityIdProperty,entityId);
+ return nil;
+ }
+
+ if( [fetchedObjects count] == 0) {
+ id entity = [NSEntityDescription insertNewObjectForEntityForName:_entityName inManagedObjectContext:managedObjectContext];
+ [entity setValue:entityId forKey:_entityIdProperty];
+ return entity;
+ }
+
+ if( [fetchedObjects count] > 1 ) {
+ OBALogSevere(@"Duplicate entities: entityName=%@ entityIdProperty=%@ entityId=%@ count=%d",_entityName,_entityIdProperty,entityId,[fetchedObjects count]);
+ (*error) = [NSError errorWithDomain:OBAErrorDomain code:kOBAErrorDuplicateEntity userInfo:nil];
+ return nil;
+ }
+
+ NSManagedObject * entity = [fetchedObjects objectAtIndex:0];
+ [self setManagedObjectIdForEntityWithId:entityId managedObjectId:[entity objectID] context:context];
+ return entity;
+}
+
+- (NSManagedObjectID*) getManagedObjectIdForEntityWithId:(NSString*)entityId withContext:(id<OBAJsonDigesterContext>)context {
+ NSDictionary * entityIdMappings = [self getEntityIdMappings:context];
+ NSDictionary * entityIdMapping = [entityIdMappings objectForKey:_entityName];
+ if( entityIdMapping == nil )
+ return nil;
+ return [entityIdMapping objectForKey:entityId];
+}
+
+- (void) setManagedObjectIdForEntityWithId:(NSString*)entityId managedObjectId:(NSManagedObjectID*)managedObjectId context:(id<OBAJsonDigesterContext>)context {
+ NSMutableDictionary * entityIdMappings = [self getEntityIdMappings:context];
+ NSMutableDictionary * entityIdMapping = [entityIdMappings objectForKey:_entityName];
+ if( entityIdMapping == nil ) {
+ entityIdMapping = [NSMutableDictionary dictionary];
+ [entityIdMappings setObject:entityIdMapping forKey:_entityName];
+ }
+ [entityIdMapping setObject:managedObjectId forKey:entityId];
+}
+
+- (NSMutableDictionary*) getEntityIdMappings:(id<OBAJsonDigesterContext>)context {
+ NSMutableDictionary * entityIdMappings = [context getParameterForKey:@"entityIdMappings"];
+ if( ! entityIdMappings ) {
+ entityIdMappings = [NSMutableDictionary dictionary];
+ [context setParamter:entityIdMappings forKey:@"entityIdMappings"];
+ }
+ return entityIdMappings;
+}
+
+@end
+
View
26 Classes/Control/Digester/OBACreateObjectJsonDigesterRule.h
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBAJsonDigester.h"
+
+
+@interface OBACreateObjectJsonDigesterRule : NSObject <OBAJsonDigesterRule> {
+ Class _objectClass;
+}
+
+- (id) initWithObjectClass:(Class)objectClass;
+
+@end
View
42 Classes/Control/Digester/OBACreateObjectJsonDigesterRule.m
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "OBACreateObjectJsonDigesterRule.h"
+
+
+@implementation OBACreateObjectJsonDigesterRule
+
+- (id) initWithObjectClass:(Class)objectClass {
+ if( self = [super init] ) {
+ _objectClass = objectClass;
+ }
+ return self;
+}
+
+#pragma mark OBAJsonDigesterRule Methods
+
+- (void) begin:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value {
+ id obj = [[_objectClass alloc] init];
+ [context pushValue:obj];
+}
+
+- (void) end:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value {
+ [context popValue];
+}
+
+
+
+@end
View
57 Classes/Control/Digester/OBAJsonDigester.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2009 bdferris <bdferris@onebusaway.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@protocol OBAJsonDigesterContext
+
+-(void) pushValue:(id)value;
+-(id) peek:(NSUInteger)index;
+-(void) popValue;
+
+- (id) getParameterForKey:(id)key;
+- (void) setParamter:(id)value forKey:(id)key;
+
+@property (nonatomic,retain) NSError * error;
+
+@end
+
+@protocol OBAJsonDigesterRule
+
+@optional
+
+- (void) begin:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value;
+- (void) end:(id<OBAJsonDigesterContext>)context name:(NSString*)name value:(id)value;
+
+@end
+
+
+@interface OBAJsonDigester : NSObject {
+ NSMutableDictionary * _rulesByPrefix;
+}
+
+- (void) addRule:(id<OBAJsonDigesterRule>)rule forPrefix:(NSString*)prefix;
+- (void) parse:(id)jsonRoot withRoot:(id)rootObject;
+- (void) parse:(id)jsonRoot withRoot:(id)rootObject parameters:(NSDictionary*)parameters;
+
+- (void) addObjectCreateRule:(Class)objectClass forPrefix:(NSString*)prefix;
+- (void) addSetPropertyRule:(NSString*)property forPrefix:(NSString*)prefix;
+- (void) addSetNext:(SEL)selector forPrefix:(NSString*)prefix;
+
+-(NSString*) extendPrefix:(NSString*)prefix withValue:(NSString*)value;
+
+@end
View
218 Classes/Control/Digester/OBAJsonDigester.m
@@ -0,0 +1,218 @@
+/**
+ * Copyright (