rhoconnect-client 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +9 -0
  3. data/CREDITS +0 -0
  4. data/LICENSE +9 -0
  5. data/README.md +47 -0
  6. data/ext/rhoconnect-client/RhoConnectClient.rb +190 -0
  7. data/ext/rhoconnect-client/ext/RhoConnectClient.xml +726 -0
  8. data/ext/rhoconnect-client/ext/build +26 -0
  9. data/ext/rhoconnect-client/ext/build.bat +30 -0
  10. data/ext/rhoconnect-client/ext/platform/android/ext_java.files +1 -0
  11. data/ext/rhoconnect-client/ext/platform/android/ext_native.files +14 -0
  12. data/ext/rhoconnect-client/ext/platform/android/src/com/rhoconnectclient/RhoconnectClient.java +1 -0
  13. data/ext/rhoconnect-client/ext/platform/iphone/.gitignore +1 -0
  14. data/ext/rhoconnect-client/ext/platform/iphone/Rakefile +74 -0
  15. data/ext/rhoconnect-client/ext/platform/iphone/RhoconnectClient.xcodeproj/project.pbxproj +390 -0
  16. data/ext/rhoconnect-client/ext/platform/iphone/RhoconnectClient_Prefix.pch +7 -0
  17. data/ext/rhoconnect-client/ext/platform/iphone/impl/readme.txt +7 -0
  18. data/ext/rhoconnect-client/ext/platform/qt/Rakefile +35 -0
  19. data/ext/rhoconnect-client/ext/platform/qt/rhoconnect-client.pro +88 -0
  20. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.sln +36 -0
  21. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.vcproj +774 -0
  22. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.vsprops +15 -0
  23. data/ext/rhoconnect-client/ext/platform/wm/src/rhoconnectclient_wm.cpp +40 -0
  24. data/ext/rhoconnect-client/ext/platform/wm/src/rhoconnectclient_wm.h +2 -0
  25. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.props +22 -0
  26. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.sln +32 -0
  27. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.vcxproj +220 -0
  28. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.vcxproj.filters +103 -0
  29. data/ext/rhoconnect-client/ext/shared/RhoConnectClientImpl.cpp +273 -0
  30. data/ext/rhoconnect-client/ext/shared/RhoConnectClientImpl.h +60 -0
  31. data/ext/rhoconnect-client/ext/shared/RhoConnectClientSingletonImpl.h +53 -0
  32. data/ext/rhoconnect-client/ext/shared/initRhoconnectClient.cpp +207 -0
  33. data/ext/rhoconnect-client/ext/shared/rhoconnectclient.c +18 -0
  34. data/ext/rhoconnect-client/ext/shared/sync/ClientRegister.cpp +398 -0
  35. data/ext/rhoconnect-client/ext/shared/sync/ClientRegister.h +147 -0
  36. data/ext/rhoconnect-client/ext/shared/sync/ISyncProtocol.h +91 -0
  37. data/ext/rhoconnect-client/ext/shared/sync/SyncEngine.cpp +1245 -0
  38. data/ext/rhoconnect-client/ext/shared/sync/SyncEngine.h +213 -0
  39. data/ext/rhoconnect-client/ext/shared/sync/SyncNotify.cpp +737 -0
  40. data/ext/rhoconnect-client/ext/shared/sync/SyncNotify.h +209 -0
  41. data/ext/rhoconnect-client/ext/shared/sync/SyncProtocol_3.h +220 -0
  42. data/ext/rhoconnect-client/ext/shared/sync/SyncProtocol_4.h +259 -0
  43. data/ext/rhoconnect-client/ext/shared/sync/SyncSource.cpp +1694 -0
  44. data/ext/rhoconnect-client/ext/shared/sync/SyncSource.h +212 -0
  45. data/ext/rhoconnect-client/ext/shared/sync/SyncThread.cpp +583 -0
  46. data/ext/rhoconnect-client/ext/shared/sync/SyncThread.h +250 -0
  47. data/ext/rhoconnect-client/ext.yml +12 -0
  48. data/lib/build/run_rhoconnect_spec.rb +135 -0
  49. data/lib/rhoconnect-client.rb +3 -0
  50. data/platform/shared/RhoConnectClient/RhoConnectClient.cpp +1673 -0
  51. data/platform/shared/RhoConnectClient/RhoConnectClient.h +181 -0
  52. data/platform/shared/RhoConnectClient/RhoError.h +77 -0
  53. data/rhoconnect-client/C++/Tests/RhoConnectClientTest.cpp +830 -0
  54. data/rhoconnect-client/C++/Tests/win32/.gitignore +3 -0
  55. data/rhoconnect-client/C++/Tests/win32/RhoConnectClient.sln +65 -0
  56. data/rhoconnect-client/C++/Tests/win32/RhoConnectClient.vcproj +634 -0
  57. data/rhoconnect-client/C++/Tests/win32/RhoConnectClientTest/RhoConnectClientTest.vcproj +222 -0
  58. data/rhoconnect-client/C++/Tests/win32/RhoConnectClientTest/stdafx.h +65 -0
  59. data/rhoconnect-client/C++/Tests/win32/stdafx.h +65 -0
  60. data/rhoconnect-client/CHANGELOG +18 -0
  61. data/rhoconnect-client/Java/Android/build/android.rake +387 -0
  62. data/rhoconnect-client/Java/Android/build/android_sdk.rb +582 -0
  63. data/rhoconnect-client/Java/Android/build/libcurl_build.files +73 -0
  64. data/rhoconnect-client/Java/Android/build/libjson_build.files +9 -0
  65. data/rhoconnect-client/Java/Android/build/librhocommon_build.files +14 -0
  66. data/rhoconnect-client/Java/Android/build/librhodb_build.files +5 -0
  67. data/rhoconnect-client/Java/Android/build/librhoimpl_build.files +13 -0
  68. data/rhoconnect-client/Java/Android/build/librholog_build.files +4 -0
  69. data/rhoconnect-client/Java/Android/build/libsqlite_build.files +1 -0
  70. data/rhoconnect-client/Java/Android/build/libsync_build.files +7 -0
  71. data/rhoconnect-client/Java/Android/build/libunzip_build.files +1 -0
  72. data/rhoconnect-client/Java/Android/build/rhoconnectclient_build.files +3 -0
  73. data/rhoconnect-client/Java/Android/build/rhoimpljava_build.files +21 -0
  74. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/Capabilities.java +63 -0
  75. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/MemoryInfoCollector.java +79 -0
  76. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/util/ContextFactory.java +63 -0
  77. data/rhoconnect-client/Java/Android/test/.classpath +9 -0
  78. data/rhoconnect-client/Java/Android/test/.project +33 -0
  79. data/rhoconnect-client/Java/Android/test/AndroidManifest.xml +14 -0
  80. data/rhoconnect-client/Java/Android/test/assets/apps/androidtest.png +0 -0
  81. data/rhoconnect-client/Java/Android/test/assets/apps/rhoconfig.txt +19 -0
  82. data/rhoconnect-client/Java/Android/test/assets/apps/rhoconfig.txt.timestamp +1 -0
  83. data/rhoconnect-client/Java/Android/test/assets/db/syncdb.schema +44 -0
  84. data/rhoconnect-client/Java/Android/test/assets/db/syncdb.triggers +10 -0
  85. data/rhoconnect-client/Java/Android/test/assets/db/syncdb_java.triggers +21 -0
  86. data/rhoconnect-client/Java/Android/test/assets/rho.dat +9 -0
  87. data/rhoconnect-client/Java/Android/test/proguard.cfg +36 -0
  88. data/rhoconnect-client/Java/Android/test/project.properties +11 -0
  89. data/rhoconnect-client/Java/Android/test/res/drawable-hdpi/icon.png +0 -0
  90. data/rhoconnect-client/Java/Android/test/res/drawable-ldpi/icon.png +0 -0
  91. data/rhoconnect-client/Java/Android/test/res/drawable-mdpi/icon.png +0 -0
  92. data/rhoconnect-client/Java/Android/test/res/layout/main.xml +12 -0
  93. data/rhoconnect-client/Java/Android/test/res/values/strings.xml +5 -0
  94. data/rhoconnect-client/Java/Android/test/rhoimpl.jar +0 -0
  95. data/rhoconnect-client/Java/Android/test/src/com/rhomobile/rhoconnect_client_test/TestRhoConnectClient.java +343 -0
  96. data/rhoconnect-client/Java/Android/test/src/com/rhomobile/rhoconnect_client_test/TestRhoConnectClientBlobs.java +219 -0
  97. data/rhoconnect-client/Java/RhoConnect/.classpath +6 -0
  98. data/rhoconnect-client/Java/RhoConnect/.project +93 -0
  99. data/rhoconnect-client/Java/RhoConnect/assets/apps/rhoconfig.txt +19 -0
  100. data/rhoconnect-client/Java/RhoConnect/assets/apps/rhoconfig.txt.timestamp +1 -0
  101. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb.schema +44 -0
  102. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb.triggers +10 -0
  103. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb_java.triggers +21 -0
  104. data/rhoconnect-client/Java/RhoConnect/assets/rho.dat +8 -0
  105. data/rhoconnect-client/Java/RhoConnect/jni/include/RhoConnectJniNotify.h +61 -0
  106. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectClient.h +181 -0
  107. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectNotify.h +13 -0
  108. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectNotify_IDelegate.h +13 -0
  109. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectObjectNotify.h +13 -0
  110. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectObjectNotify_IDelegate.h +13 -0
  111. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhomModel.h +103 -0
  112. data/rhoconnect-client/Java/RhoConnect/jni/include/rhojava.inc +76 -0
  113. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniClient.cpp +401 -0
  114. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniModel.cpp +332 -0
  115. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniNotify.cpp +223 -0
  116. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectUtil.cpp +82 -0
  117. data/rhoconnect-client/Java/RhoConnect/jni/src/RhodesApp.cpp +114 -0
  118. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectClient.java +108 -0
  119. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectNotify.java +78 -0
  120. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectObjectNotify.java +71 -0
  121. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhomModel.java +195 -0
  122. data/rhoconnect-client/JavaScript/.classpath +10 -0
  123. data/rhoconnect-client/JavaScript/.gitignore +4 -0
  124. data/rhoconnect-client/JavaScript/.project +17 -0
  125. data/rhoconnect-client/JavaScript/README.textile +1 -0
  126. data/rhoconnect-client/JavaScript/build.xml +185 -0
  127. data/rhoconnect-client/JavaScript/doc/fsm-sample.js +44 -0
  128. data/rhoconnect-client/JavaScript/doc/fsm-sample.png +0 -0
  129. data/rhoconnect-client/JavaScript/src/RhoSyncJS.gwt.xml +21 -0
  130. data/rhoconnect-client/JavaScript/stubs/RhoSyncStubsJS.gwt.xml +21 -0
  131. data/rhoconnect-client/JavaScript/stubs/com/rho/Capabilities.java +7 -0
  132. data/rhoconnect-client/JavaScript/stubs/com/rho/IRhoRubyHelper.java +7 -0
  133. data/rhoconnect-client/JavaScript/stubs/com/rho/Mutex.java +5 -0
  134. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoAppAdapter.java +39 -0
  135. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoClassFactory.java +29 -0
  136. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoConf.java +100 -0
  137. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoEmptyLogger.java +7 -0
  138. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoEmptyProfiler.java +5 -0
  139. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoLogger.java +32 -0
  140. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoProfiler.java +27 -0
  141. data/rhoconnect-client/JavaScript/stubs/com/rho/RhodesApp.java +25 -0
  142. data/rhoconnect-client/JavaScript/stubs/com/rho/TimeInterval.java +22 -0
  143. data/rhoconnect-client/JavaScript/stubs/com/rho/Tokenizer.java +23 -0
  144. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBAdapter.java +174 -0
  145. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBAttrManager.java +15 -0
  146. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBException.java +5 -0
  147. data/rhoconnect-client/JavaScript/stubs/com/rho/db/IDBResult.java +27 -0
  148. data/rhoconnect-client/JavaScript/stubs/com/rho/file/IFileAccess.java +7 -0
  149. data/rhoconnect-client/JavaScript/stubs/com/rho/file/SimpleFile.java +15 -0
  150. data/rhoconnect-client/JavaScript/stubs/com/rho/net/IHttpConnection.java +22 -0
  151. data/rhoconnect-client/JavaScript/stubs/com/rho/net/NetRequest.java +324 -0
  152. data/rhoconnect-client/JavaScript/stubs/com/rho/net/NetResponse.java +51 -0
  153. data/rhoconnect-client/JavaScript/stubs/com/rho/net/URI.java +64 -0
  154. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/ClientRegister.java +15 -0
  155. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONArrayIterator.java +37 -0
  156. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONEntry.java +48 -0
  157. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONStructIterator.java +41 -0
  158. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/SyncNotify.java +98 -0
  159. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/SyncThread.java +92 -0
  160. data/rhoconnect-client/JavaScript/war/WEB-INF/lib/gwt-servlet-deps.jar +0 -0
  161. data/rhoconnect-client/JavaScript/war/WEB-INF/lib/gwt-servlet.jar +0 -0
  162. data/rhoconnect-client/JavaScript/war/js/fsm-sample.js +54 -0
  163. data/rhoconnect-client/JavaScript/war/js/rhosync-api.js +237 -0
  164. data/rhoconnect-client/JavaScript/war/js/rhosync-fsm.js +307 -0
  165. data/rhoconnect-client/JavaScript/war/rhosyncjs/4C71D69C9BBC9E6F05C6BA49B01BCBC1.cache.html +3122 -0
  166. data/rhoconnect-client/JavaScript/war/rhosyncjs/5146F4FFF34511C8BB2661E920B49E3A.cache.html +3254 -0
  167. data/rhoconnect-client/JavaScript/war/rhosyncjs/5248C67481D9D27AD0703D15CDBD2A1C.cache.html +3147 -0
  168. data/rhoconnect-client/JavaScript/war/rhosyncjs/EE1DC2692C9C32367B53A39E2358AF23.cache.html +3195 -0
  169. data/rhoconnect-client/JavaScript/war/rhosyncjs/clear.cache.gif +0 -0
  170. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/corner.png +0 -0
  171. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/corner_ie6.png +0 -0
  172. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/hborder.png +0 -0
  173. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/hborder_ie6.png +0 -0
  174. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/corner_dialog_topleft.png +0 -0
  175. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/corner_dialog_topright.png +0 -0
  176. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/hborder_blue_shadow.png +0 -0
  177. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/hborder_gray_shadow.png +0 -0
  178. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/vborder_blue_shadow.png +0 -0
  179. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/vborder_gray_shadow.png +0 -0
  180. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/splitPanelThumb.png +0 -0
  181. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/vborder.png +0 -0
  182. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/vborder_ie6.png +0 -0
  183. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/standard.css +1144 -0
  184. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/standard_rtl.css +1145 -0
  185. data/rhoconnect-client/JavaScript/war/rhosyncjs/hosted.html +350 -0
  186. data/rhoconnect-client/JavaScript/war/rhosyncjs/rhosyncjs.nocache.js +314 -0
  187. data/rhoconnect-client/JavaScript/war/test/SpecRunner.html +35 -0
  188. data/rhoconnect-client/JavaScript/war/test/dbtest.html +38 -0
  189. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/MIT.LICENSE +20 -0
  190. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine-html.js +188 -0
  191. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine.css +166 -0
  192. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine.js +2421 -0
  193. data/rhoconnect-client/JavaScript/war/test/spec/SpecHelper.js +7 -0
  194. data/rhoconnect-client/JavaScript/war/test/spec/SyncApiSpec.js +573 -0
  195. data/rhoconnect-client/JavaScript/war/test/spec/samples/PlayerSpec.js +58 -0
  196. data/rhoconnect-client/JavaScript/war/test/worker-test.js +17 -0
  197. data/rhoconnect-client/LICENSE +41 -0
  198. data/rhoconnect-client/ObjectiveC/RhoConnectClient.h +118 -0
  199. data/rhoconnect-client/ObjectiveC/RhoConnectClient.m +641 -0
  200. data/rhoconnect-client/ObjectiveC/RhoConnectClient.xcodeproj/project.pbxproj +1434 -0
  201. data/rhoconnect-client/ObjectiveC/RhoConnectNotify.h +83 -0
  202. data/rhoconnect-client/ObjectiveC/RhoConnectNotify.m +181 -0
  203. data/rhoconnect-client/ObjectiveC/RhoConnectObjectNotify.h +65 -0
  204. data/rhoconnect-client/ObjectiveC/RhoConnectObjectNotify.m +73 -0
  205. data/rhoconnect-client/ObjectiveC/RhomModel.h +101 -0
  206. data/rhoconnect-client/ObjectiveC/RhomModel.m +320 -0
  207. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/MainWindow.xib +198 -0
  208. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest-Info.plist +30 -0
  209. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest.xcodeproj/project.pbxproj +373 -0
  210. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTestAppDelegate.h +58 -0
  211. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTestAppDelegate.m +84 -0
  212. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest_Prefix.pch +8 -0
  213. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/invalid_import_db.zip +0 -0
  214. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/main.m +1096 -0
  215. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/test.png +0 -0
  216. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/test2.png +0 -0
  217. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/valid_import_db.zip +0 -0
  218. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsAppDelegate.h +62 -0
  219. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsAppDelegate.m +35 -0
  220. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsViewController.h +78 -0
  221. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsViewController.m +549 -0
  222. data/rhoconnect-client/ObjectiveC/Tests/ptests/MainWindow.xib +227 -0
  223. data/rhoconnect-client/ObjectiveC/Tests/ptests/main.m +17 -0
  224. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests-Info.plist +30 -0
  225. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests.xcodeproj/project.pbxproj +363 -0
  226. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptestsViewController.xib +641 -0
  227. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests_Prefix.pch +8 -0
  228. data/rhoconnect-client/README.textile +23 -0
  229. data/rhoconnect-client/Rakefile +20 -0
  230. data/rhoconnect-client/Samples/Java/android_store/.classpath +8 -0
  231. data/rhoconnect-client/Samples/Java/android_store/.project +33 -0
  232. data/rhoconnect-client/Samples/Java/android_store/AndroidManifest.xml +24 -0
  233. data/rhoconnect-client/Samples/Java/android_store/assets/apps/rhoconfig.txt +19 -0
  234. data/rhoconnect-client/Samples/Java/android_store/assets/apps/rhoconfig.txt.timestamp +1 -0
  235. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb.schema +44 -0
  236. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb.triggers +10 -0
  237. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb_java.triggers +21 -0
  238. data/rhoconnect-client/Samples/Java/android_store/assets/rho.dat +8 -0
  239. data/rhoconnect-client/Samples/Java/android_store/default.properties +11 -0
  240. data/rhoconnect-client/Samples/Java/android_store/project.properties +14 -0
  241. data/rhoconnect-client/Samples/Java/android_store/res/drawable-hdpi/icon.png +0 -0
  242. data/rhoconnect-client/Samples/Java/android_store/res/drawable-ldpi/icon.png +0 -0
  243. data/rhoconnect-client/Samples/Java/android_store/res/drawable-mdpi/icon.png +0 -0
  244. data/rhoconnect-client/Samples/Java/android_store/res/layout/main.xml +12 -0
  245. data/rhoconnect-client/Samples/Java/android_store/res/values/strings.xml +5 -0
  246. data/rhoconnect-client/Samples/Java/android_store/rhoimpl.jar +0 -0
  247. data/rhoconnect-client/Samples/Java/android_store/src/com/rhomobile/android_store/StoreActivity.java +68 -0
  248. data/rhoconnect-client/Samples/Java/android_store/src/com/rhomobile/android_store/StoreApplication.java +15 -0
  249. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/LoginViewController.h +70 -0
  250. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/LoginViewController.m +94 -0
  251. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RhoConnectEngine.h +82 -0
  252. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RhoConnectEngine.m +119 -0
  253. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RootViewController.h +63 -0
  254. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RootViewController.m +314 -0
  255. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/WaitLoginController.h +65 -0
  256. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/WaitLoginController.m +110 -0
  257. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/storeAppDelegate.h +61 -0
  258. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/storeAppDelegate.m +171 -0
  259. data/rhoconnect-client/Samples/ObjectiveC/store/LoginViewController.xib +779 -0
  260. data/rhoconnect-client/Samples/ObjectiveC/store/MainWindow.xib +580 -0
  261. data/rhoconnect-client/Samples/ObjectiveC/store/RootViewController.xib +384 -0
  262. data/rhoconnect-client/Samples/ObjectiveC/store/WaitLoginController.xib +557 -0
  263. data/rhoconnect-client/Samples/ObjectiveC/store/icon.png +0 -0
  264. data/rhoconnect-client/Samples/ObjectiveC/store/main.m +22 -0
  265. data/rhoconnect-client/Samples/ObjectiveC/store/store-Info.plist +30 -0
  266. data/rhoconnect-client/Samples/ObjectiveC/store/store.xcodeproj/project.pbxproj +367 -0
  267. data/rhoconnect-client/Samples/ObjectiveC/store/store_Prefix.pch +14 -0
  268. data/rhoconnect-client/build.yml +3 -0
  269. data/rhoconnect-client/version +1 -0
  270. metadata +314 -0
@@ -0,0 +1,147 @@
1
+ /*------------------------------------------------------------------------
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008-2011 Rhomobile, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * http://rhomobile.com
25
+
26
+ * Copyright (c) 2011-2016 Symbol Technologies, Inc.
27
+ *
28
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * http://symbol.com
47
+ *------------------------------------------------------------------------*/
48
+
49
+ #pragma once
50
+ #ifdef __cplusplus
51
+
52
+ #include "logging/RhoLog.h"
53
+ #include "common/RhoThread.h"
54
+ #include "common/RhoStd.h"
55
+ #include "net/INetRequest.h"
56
+ #include "common/IRhoClassFactory.h"
57
+
58
+ namespace rho{
59
+ namespace sync{
60
+
61
+ class ILoginListener;
62
+ class CSyncEngine;
63
+
64
+ #define WAIT_BEFOREKILL_SECONDS 3
65
+ #define POLL_INTERVAL_SECONDS 60
66
+ #define POLL_INTERVAL_INFINITE (unsigned int)(-1)
67
+ #define DEFAULT_PUSH_PORT 100
68
+
69
+ class CClientRegister : protected common::CRhoThread
70
+ {
71
+ DEFINE_LOGCLASS;
72
+
73
+ static CClientRegister* m_pInstance;
74
+ static bool s_sslVerifyPeer;
75
+ static VectorPtr<ILoginListener*> s_loginListeners;
76
+
77
+ NetRequest m_NetRequest;
78
+ String m_strDevicePin;
79
+ unsigned int m_nPollInterval;
80
+
81
+
82
+ enum EnState
83
+ {
84
+ stRegister,
85
+ stUnregister
86
+ };
87
+
88
+ EnState m_state;
89
+ common::CMutex m_mxStateAccess;
90
+ String m_unregisterSession;
91
+ String m_unregisterClientID;
92
+
93
+ public:
94
+ static void SetSslVerifyPeer(boolean b);
95
+ static bool GetSslVerifyPeer();
96
+ static void AddLoginListener(ILoginListener* listener);
97
+ static CClientRegister* Get();
98
+ static CClientRegister* Create();
99
+ static CClientRegister* Create(const String& devicePin);
100
+ static void Stop();
101
+ static void Destroy();
102
+ static CClientRegister* getInstance() { return m_pInstance; }
103
+
104
+ void setRhoconnectCredentials(const String& user, const String& pass, const String& session);
105
+ void dropRhoconnectCredentials(const String& session,const String& clientID);
106
+ void setDevicehPin(const String& pin);
107
+ const String& getDevicePin() const { return m_strDevicePin; }
108
+
109
+ void startUp();
110
+
111
+ protected:
112
+ virtual void run();
113
+
114
+ private:
115
+ String getRegisterBody(const String& strClientID);
116
+ String getUnregisterBody(const String& strClientID);
117
+
118
+ CClientRegister();
119
+ ~CClientRegister();
120
+
121
+ void doStop();
122
+ boolean doRegister(CSyncEngine& oSync);
123
+ boolean doUnregister(CSyncEngine& oSync);
124
+
125
+ net::CNetRequestWrapper getNet(){ return getNetRequest(&m_NetRequest); }
126
+
127
+ void notifyLoggedIn(const String& user, const String& pass, const String& session);
128
+ void notifyLoggedOut(const String& session);
129
+
130
+ void setState( EnState st );
131
+ EnState getState();
132
+
133
+ };
134
+
135
+ }
136
+ }
137
+ #endif //__cplusplus
138
+
139
+ #ifdef __cplusplus
140
+ extern "C" {
141
+ #endif //__cplusplus
142
+
143
+ void rho_clientregister_create(const char* szDevicePin);
144
+
145
+ #ifdef __cplusplus
146
+ };
147
+ #endif //__cplusplus
@@ -0,0 +1,91 @@
1
+ /*------------------------------------------------------------------------
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008-2011 Rhomobile, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * http://rhomobile.com
25
+
26
+ * Copyright (c) 2011-2016 Symbol Technologies, Inc.
27
+ *
28
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * http://symbol.com
47
+ *------------------------------------------------------------------------*/
48
+
49
+ #pragma once
50
+
51
+ #include "common/RhoStd.h"
52
+
53
+ namespace rho {
54
+ namespace sync {
55
+
56
+ struct ISyncProtocol
57
+ {
58
+ virtual ~ISyncProtocol() {}
59
+
60
+ virtual const String& getClientIDHeader() const = 0;
61
+ virtual const String& getContentType() const = 0;
62
+ virtual int getVersion() const = 0;
63
+
64
+ virtual String getLoginUrl() = 0;
65
+ virtual String getLoginBody( const String& name, const String& password)=0;
66
+
67
+ virtual const char* getClientCreateMethod() = 0;
68
+ virtual String getClientCreateUrl() = 0;
69
+
70
+ virtual String getClientRegisterUrl(const String& strClientID) = 0;
71
+ virtual String getClientRegisterBody(const String& strClientID, const String& strPin, int nPort, const String& strType, const String& strPhoneID, const String& strDevicePushType = "") = 0;
72
+ virtual String getClientAnsRegisterBody(const String& strClientID, const String& strPin, int nPort, const String& strType, const String& strPhoneID ) = 0;
73
+
74
+ virtual const char* getClientResetMethod() = 0;
75
+ virtual String getClientResetUrl(const String& strClientID) = 0;
76
+ virtual String getClientResetBody() = 0;
77
+
78
+ virtual String getClientChangesUrl(const String& srcName) = 0;
79
+ virtual String getServerQueryUrl(const String& strSrcName, const String& strClientID, int nPageSize )=0;
80
+
81
+ virtual const char* getServerSearchMethod() = 0;
82
+ virtual String getServerSearchUrl(const String& strClientID, int nPageSize, const String& strFrom, const Vector<String>& sources, const Hashtable<String, String>& source_tokens) = 0;
83
+ virtual String getServerSearchBody(int nPageSize, const Vector<String>& sources, const Hashtable<String, String>& source_tokens )=0;
84
+
85
+ virtual const char* getServerBulkDataMethod() = 0;
86
+ virtual String getServerBulkDataUrl(const String& strClientID, const String& strPartition, const Vector<String>& sources) = 0;
87
+ virtual String getServerBulkDataBody(const String& strPartition, const Vector<String>& sources) = 0;
88
+ };
89
+
90
+ }
91
+ }
@@ -0,0 +1,1245 @@
1
+ /*------------------------------------------------------------------------
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008-2011 Rhomobile, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * http://rhomobile.com
25
+
26
+ * Copyright (c) 2011-2016 Symbol Technologies, Inc.
27
+ *
28
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * http://symbol.com
47
+ *------------------------------------------------------------------------*/
48
+
49
+ #include "SyncEngine.h"
50
+ #include "SyncSource.h"
51
+ #include "SyncThread.h"
52
+
53
+ #include "json/JSONIterator.h"
54
+ #include "common/RhoConf.h"
55
+ #include "common/StringConverter.h"
56
+ #include "sync/ClientRegister.h"
57
+ #include "net/URI.h"
58
+ #include "statistic/RhoProfiler.h"
59
+ #include "common/RhoTime.h"
60
+ #include "common/RhoFilePath.h"
61
+ #include "common/RhoFile.h"
62
+ #include "common/RhoAppAdapter.h"
63
+ #include "SyncProtocol_4.h"
64
+ #include "SyncProtocol_3.h"
65
+ #include "common/RhoSettingsDefs.h"
66
+ #include "common/Tokenizer.h"
67
+
68
+ #ifdef _MSC_VER
69
+ // Disable warnings about using "this" in member initializater list
70
+ #pragma warning(disable: 4355)
71
+ #endif
72
+
73
+ namespace rho {
74
+ namespace sync {
75
+ IMPLEMENT_LOGCLASS(CSyncEngine,"Sync");
76
+
77
+ using namespace rho::net;
78
+ using namespace rho::common;
79
+ using namespace rho::json;
80
+ CSyncEngine::CSourceOptions CSyncEngine::m_oSourceOptions;
81
+
82
+ CSyncEngine::CSyncEngine(): m_syncState(esNone), m_oSyncNotify(*this)
83
+ {
84
+ m_bNoThreaded = false;
85
+ m_bStopByUser = false;
86
+ m_nSyncPageSize = 2000;
87
+
88
+ initProtocol();
89
+ }
90
+
91
+ void CSyncEngine::initProtocol()
92
+ {
93
+ int protocolVersion = RHOCONF().getInt("rc_protocol_version");
94
+ switch(protocolVersion) {
95
+ case 3:
96
+ m_SyncProtocol = new CSyncProtocol_3();
97
+ break;
98
+ default:
99
+ // unknown version - use V4
100
+ LOG(ERROR) + "Unknown Sync Protocol Version has been requested: " + convertToStringA(protocolVersion) + ", using Version 4 instead.";
101
+ // no break here - intentionally - to proceed with version 4
102
+ case 0: // 0 - means default
103
+ case 4:
104
+ m_SyncProtocol = new CSyncProtocol_4();
105
+ break;
106
+ }
107
+ }
108
+
109
+ void CSyncEngine::setSslVerifyPeer(boolean b)
110
+ {
111
+ m_NetRequest.setSslVerifyPeer(b);
112
+ m_NetRequestClientID.setSslVerifyPeer(b);
113
+
114
+ CClientRegister::SetSslVerifyPeer(b);
115
+ }
116
+
117
+ bool CSyncEngine::getSslVerifyPeer()
118
+ {
119
+ return m_NetRequest.getSslVerifyPeer() && m_NetRequestClientID.getSslVerifyPeer() && CClientRegister::GetSslVerifyPeer();
120
+ }
121
+
122
+ void CSyncEngine::CSourceOptions::setProperty(int nSrcID, const char* szPropName, const char* szPropValue)
123
+ {
124
+ synchronized(m_mxSrcOptions)
125
+ {
126
+ Hashtable<String,String>* phashOptions = m_hashSrcOptions.get(nSrcID);
127
+ if ( phashOptions == null )
128
+ {
129
+ phashOptions = new Hashtable<String,String>();
130
+ m_hashSrcOptions.put( nSrcID, phashOptions );
131
+ }
132
+
133
+ Hashtable<String,String>& hashOptions = *phashOptions;
134
+ hashOptions.put(szPropName,szPropValue!=null?szPropValue:"");
135
+ }
136
+ }
137
+
138
+ String CSyncEngine::CSourceOptions::getProperty(int nSrcID, const char* szPropName)
139
+ {
140
+ String res = "";
141
+ synchronized(m_mxSrcOptions)
142
+ {
143
+ Hashtable<String,String>* phashOptions = m_hashSrcOptions.get(nSrcID);
144
+ if ( phashOptions != null )
145
+ {
146
+ Hashtable<String,String>& hashOptions = *phashOptions;
147
+ res = hashOptions.get(szPropName);
148
+ }
149
+ }
150
+
151
+ return res;
152
+ }
153
+
154
+ boolean CSyncEngine::CSourceOptions::getBoolProperty(int nSrcID, const char* szPropName)
155
+ {
156
+ String strValue = getProperty(nSrcID, szPropName);
157
+
158
+ return strValue.compare("1") == 0 || strValue.compare("true") == 0 ? true : false;
159
+ }
160
+
161
+ int CSyncEngine::CSourceOptions::getIntProperty(int nSrcID, const char* szPropName)
162
+ {
163
+ String strValue = getProperty(nSrcID, szPropName);
164
+
165
+ return strValue.length() ? atoi(strValue.c_str()) : 0;
166
+ }
167
+
168
+ void CSyncEngine::CSourceOptions::clearProperties()
169
+ {
170
+ synchronized(m_mxSrcOptions)
171
+ {
172
+ m_hashSrcOptions.clear();
173
+ }
174
+ }
175
+
176
+ void CSyncEngine::prepareSync(ESyncState eState, const CSourceID* oSrcID)
177
+ {
178
+ setState(eState);
179
+ m_bIsSearch = eState == esSearch;
180
+ m_bStopByUser = false;
181
+ m_nErrCode = RhoAppAdapter.ERR_NONE;
182
+ m_strError = "";
183
+ m_bIsSchemaChanged = false;
184
+
185
+ loadAllSources();
186
+
187
+ m_strSession = loadSession();
188
+ if ( isSessionExist() )
189
+ {
190
+ m_clientID = loadClientID();
191
+ if ( m_nErrCode == RhoAppAdapter.ERR_NONE )
192
+ {
193
+ getNotify().cleanLastSyncObjectCount();
194
+ doBulkSync();
195
+
196
+ return;
197
+ }
198
+ }else
199
+ m_nErrCode = RhoAppAdapter.ERR_CLIENTISNOTLOGGEDIN;
200
+
201
+ CSyncSource* src = null;
202
+ if ( oSrcID != null )
203
+ src = findSource(*oSrcID);
204
+
205
+ if ( src != null )
206
+ {
207
+ src->m_nErrCode = m_nErrCode;
208
+ src->m_strError = m_strError;
209
+ getNotify().fireSyncNotification(src, true, src->m_nErrCode, "");
210
+ }else
211
+ {
212
+ getNotify().fireAllSyncNotifications(true, m_nErrCode, m_strError/*, ""*/ );
213
+ }
214
+
215
+ stopSync();
216
+ }
217
+
218
+ void CSyncEngine::doSyncAllSources(const String& strQueryParams, boolean bSyncOnlyChangedSources)
219
+ {
220
+ prepareSync(esSyncAllSources, null);
221
+
222
+ if ( isContinueSync() )
223
+ {
224
+ PROF_CREATE_COUNTER("Net");
225
+ PROF_CREATE_COUNTER("Parse");
226
+ PROF_CREATE_COUNTER("DB");
227
+ PROF_CREATE_COUNTER("Data");
228
+ PROF_CREATE_COUNTER("Data1");
229
+ PROF_CREATE_COUNTER("Pull");
230
+ PROF_START("Sync");
231
+
232
+ syncAllSources(strQueryParams, bSyncOnlyChangedSources);
233
+
234
+ PROF_DESTROY_COUNTER("Net");
235
+ PROF_DESTROY_COUNTER("Parse");
236
+ PROF_DESTROY_COUNTER("DB");
237
+ PROF_DESTROY_COUNTER("Data");
238
+ PROF_DESTROY_COUNTER("Data1");
239
+ PROF_DESTROY_COUNTER("Pull");
240
+ PROF_STOP("Sync");
241
+
242
+ }
243
+
244
+ getNotify().cleanCreateObjectErrors();
245
+
246
+ if ( getState() != esExit )
247
+ setState(esNone);
248
+ }
249
+
250
+ bool CSyncEngine::recoverSearch(const String& strUrl, const String& strBody, int& errorCode, String& strError, int nProgressStep ) {
251
+
252
+ LOG(INFO) + "Call search on server for previous request. Url: " + (strUrl);
253
+
254
+ Hashtable<String, String> reqHeaders;
255
+ reqHeaders.put(getProtocol().getClientIDHeader(), getClientID());
256
+
257
+ NetResponse resp = getNet().doRequest(getProtocol().getServerSearchMethod(),
258
+ strUrl, strBody, this, &reqHeaders);
259
+
260
+ if ( !resp.isOK() )
261
+ {
262
+ errorCode = RhoAppAdapter.getErrorFromResponse(resp);
263
+ strError = resp.getCharData();
264
+ return false;
265
+ }
266
+
267
+ const char* szData = resp.getCharData();
268
+
269
+ CJSONArrayIterator oJsonArr(szData);
270
+
271
+ for( ; !oJsonArr.isEnd() ; oJsonArr.next() )
272
+ {
273
+ CJSONArrayIterator oSrcArr(oJsonArr.getCurItem());
274
+ if (oSrcArr.isEnd())
275
+ break;
276
+
277
+ int nVersion = 0;
278
+ if ( !oSrcArr.isEnd() && oSrcArr.getCurItem().hasName("version") )
279
+ {
280
+ nVersion = oSrcArr.getCurItem().getInt("version");
281
+ oSrcArr.next();
282
+ }
283
+
284
+ if ( nVersion != getProtocol().getVersion() )
285
+ {
286
+ LOG(ERROR) + "Sync server send search data with incompatible version. Client version: " + convertToStringA(getProtocol().getVersion()) +
287
+ "; Server response version: " + convertToStringA(nVersion);
288
+ errorCode = RhoAppAdapter.ERR_SYNCVERSION;
289
+ return false;
290
+ }
291
+
292
+ if ( !oSrcArr.isEnd() && oSrcArr.getCurItem().hasName("token"))
293
+ {
294
+ oSrcArr.next();
295
+ }
296
+
297
+ if ( !oSrcArr.getCurItem().hasName("source") )
298
+ {
299
+ LOG(ERROR) + "Sync server send search data without source name.";
300
+ errorCode = RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE;
301
+ strError = szData;
302
+ return false;
303
+ }
304
+
305
+ String strSrcName = oSrcArr.getCurItem().getString("source");
306
+ CSyncSource* pSrc = findSourceByName(strSrcName);
307
+ if ( pSrc == null )
308
+ {
309
+ LOG(ERROR) + "Sync server send search data for unknown source name:" + strSrcName;
310
+ errorCode = RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE;
311
+ strError = szData;
312
+ return false;
313
+ }
314
+
315
+ oSrcArr.reset(0);
316
+ pSrc->setProgressStep(nProgressStep);
317
+
318
+ pSrc->processServerResponse_ver3(oSrcArr,true);
319
+ }
320
+
321
+ return true;
322
+ }
323
+
324
+ void CSyncEngine::doSearch(rho::Vector<rho::String>& arSources, String strParams, const String& strFrom, boolean bSearchSyncChanges, int nProgressStep)
325
+ {
326
+ prepareSync(esSearch, null);
327
+ if ( !isContinueSync() )
328
+ {
329
+ if ( getState() != esExit )
330
+ setState(esNone);
331
+
332
+ return;
333
+ }
334
+
335
+ CTimeInterval startTime = CTimeInterval::getCurrentTime();
336
+
337
+ if ( bSearchSyncChanges )
338
+ {
339
+ for ( int i = 0; i < (int)arSources.size(); i++ )
340
+ {
341
+ CSyncSource* pSrc = findSourceByName(arSources.elementAt(i));
342
+ if ( pSrc != null )
343
+ pSrc->syncClientChanges();
344
+ }
345
+ }
346
+
347
+ while( isContinueSync() )
348
+ {
349
+ int nSearchCount = 0;
350
+
351
+ /* Recover state if previous search request wasn't successful. */
352
+ if ( (RHOCONF().isExist("search_request")) && (RHOCONF().getString("search_request").length()>0) ) {
353
+ String strError = "";
354
+ int errorCode = 0;
355
+ if (!recoverSearch(RHOCONF().getString("search_request_url"),RHOCONF().getString("search_request_body"), errorCode,strError,nProgressStep)) {
356
+ stopSync();
357
+ m_nErrCode = errorCode;
358
+ m_strError = strError;
359
+ continue;
360
+ }
361
+
362
+ RHOCONF().setString("search_request_url", "", true);
363
+ RHOCONF().setString("search_request_body", "", true);
364
+ }
365
+
366
+
367
+ String strSearchParams;
368
+ if ( strParams.length() > 0 )
369
+ strSearchParams += strParams.at(0) == '&' ? strParams : "&" + strParams;
370
+
371
+ String strTestResp = "";
372
+ Hashtable<String, String> source_tokens;
373
+ Hashtable<String, String> recover_tokens;
374
+ for ( int i = 0; i < (int)arSources.size(); i++ )
375
+ {
376
+ CSyncSource* pSrc = findSourceByName(arSources.elementAt(i));
377
+ if ( pSrc != null )
378
+ {
379
+ String source_token;
380
+ if ( !pSrc->isTokenFromDB() && pSrc->getToken() > 1 )
381
+ source_token = convertToStringA(pSrc->getToken());
382
+
383
+ source_tokens.put(pSrc->getName(), source_token);
384
+ recover_tokens.put(pSrc->getName(), "resend_token");
385
+
386
+ strTestResp = getSourceOptions().getProperty(pSrc->getID(), "rho_server_response");
387
+ }
388
+ }
389
+ String strUrl = getProtocol().getServerSearchUrl(getClientID(), getSyncPageSize(), strFrom, arSources, source_tokens) + strSearchParams;
390
+ String strRecoverUrl = getProtocol().getServerSearchUrl(getClientID(), getSyncPageSize(), strFrom, arSources, recover_tokens) + strSearchParams;
391
+ // for recover URL - set 'resend ' parameter
392
+ strRecoverUrl += "&resend=1";
393
+ Hashtable<String, String> reqHeaders;
394
+ reqHeaders.put(getProtocol().getClientIDHeader(), getClientID());
395
+ String strBody = getProtocol().getServerSearchBody(getSyncPageSize(), arSources, source_tokens);
396
+ String strRecoverBody = getProtocol().getServerSearchBody(getSyncPageSize(), arSources, recover_tokens);
397
+
398
+ LOG(INFO) + "Call search on server. Url: " + (strUrl);
399
+ // for recover URL - set 'resend ' parameter and store for recovery
400
+ strRecoverUrl += "&resend=1";
401
+ RHOCONF().setString("search_request_url", strRecoverUrl, true);
402
+ RHOCONF().setString("search_request_body", strRecoverBody, true);
403
+
404
+ NetResponse resp = getNet().doRequest(getProtocol().getServerSearchMethod(),
405
+ strUrl, strBody, this, &reqHeaders);
406
+
407
+ // when request is completed - reset the recovery
408
+ RHOCONF().setString("search_request_url", "", true);
409
+ RHOCONF().setString("search_request_body", "", true);
410
+
411
+ if ( !resp.isOK() )
412
+ {
413
+ stopSync();
414
+ m_nErrCode = RhoAppAdapter.getErrorFromResponse(resp);
415
+ m_strError = resp.getCharData();
416
+ continue;
417
+ }
418
+
419
+ const char* szData = null;
420
+ if ( strTestResp.length() > 0 )
421
+ {
422
+ szData = strTestResp.c_str();
423
+ getNotify().setFakeServerResponse(true);
424
+ }
425
+ else
426
+ szData = resp.getCharData();
427
+
428
+ //LOG(INFO) + szData;
429
+ CJSONArrayIterator oJsonArr(szData);
430
+
431
+ for( ; !oJsonArr.isEnd() && isContinueSync(); oJsonArr.next() )
432
+ {
433
+ CJSONArrayIterator oSrcArr(oJsonArr.getCurItem());
434
+ if (oSrcArr.isEnd())
435
+ break;
436
+
437
+ int nVersion = 0;
438
+ if ( !oSrcArr.isEnd() && oSrcArr.getCurItem().hasName("version") )
439
+ {
440
+ nVersion = oSrcArr.getCurItem().getInt("version");
441
+ oSrcArr.next();
442
+ }
443
+
444
+ if ( nVersion != getProtocol().getVersion() )
445
+ {
446
+ LOG(ERROR) + "Sync server send search data with incompatible version. Client version: " + convertToStringA(getProtocol().getVersion()) +
447
+ "; Server response version: " + convertToStringA(nVersion);
448
+ stopSync();
449
+ m_nErrCode = RhoAppAdapter.ERR_SYNCVERSION;
450
+ continue;
451
+ }
452
+
453
+ if ( !oSrcArr.isEnd() && oSrcArr.getCurItem().hasName("token"))
454
+ {
455
+ oSrcArr.next();
456
+ }
457
+
458
+ if ( !oSrcArr.getCurItem().hasName("source") )
459
+ {
460
+ LOG(ERROR) + "Sync server send search data without source name.";
461
+ stopSync();
462
+ m_nErrCode = RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE;
463
+ m_strError = szData;
464
+ continue;
465
+ }
466
+
467
+ String strSrcName = oSrcArr.getCurItem().getString("source");
468
+ CSyncSource* pSrc = findSourceByName(strSrcName);
469
+ if ( pSrc == null )
470
+ {
471
+ LOG(ERROR) + "Sync server send search data for unknown source name:" + strSrcName;
472
+ stopSync();
473
+ m_nErrCode = RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE;
474
+ m_strError = szData;
475
+ continue;
476
+ }
477
+
478
+ oSrcArr.reset(0);
479
+ pSrc->setProgressStep(nProgressStep);
480
+ pSrc->processServerResponse_ver3(oSrcArr);
481
+
482
+ nSearchCount += pSrc->getCurPageCount();
483
+ }
484
+
485
+ if ( nSearchCount == 0 )
486
+ {
487
+ for ( int i = 0; i < (int)arSources.size(); i++ )
488
+ {
489
+ CSyncSource* pSrc = findSourceByName(arSources.elementAt(i));
490
+ if ( pSrc != null )
491
+ pSrc->processToken(0);
492
+ }
493
+
494
+ break;
495
+ }
496
+
497
+ if ( strTestResp.length() > 0 )
498
+ break;
499
+ }
500
+
501
+ getNotify().fireAllSyncNotifications(true, m_nErrCode, m_strError);
502
+
503
+ //update db info
504
+ CTimeInterval endTime = CTimeInterval::getCurrentTime();
505
+ unsigned long timeUpdated = CLocalTime().toULong();
506
+ for ( int i = 0; i < (int)arSources.size(); i++ )
507
+ {
508
+ CSyncSource* pSrc = findSourceByName(arSources.elementAt(i));
509
+ if ( pSrc == null )
510
+ continue;
511
+ CSyncSource& oSrc = *pSrc;
512
+ oSrc.getDB().executeSQL("UPDATE sources set last_updated=?,last_inserted_size=?,last_deleted_size=?, \
513
+ last_sync_duration=?,last_sync_success=?, backend_refresh_time=? WHERE source_id=?",
514
+ timeUpdated, oSrc.getInsertedCount(), oSrc.getDeletedCount(),
515
+ (endTime-startTime).toULong(), oSrc.m_nErrCode == RhoAppAdapter.ERR_NONE, oSrc.getRefreshTime(),
516
+ oSrc.getID() );
517
+ }
518
+ //
519
+
520
+ getNotify().cleanCreateObjectErrors();
521
+ if ( getState() != esExit )
522
+ setState(esNone);
523
+ }
524
+
525
+ void CSyncEngine::doSyncSource(const CSourceID& oSrcID, const String& strQueryParams)
526
+ {
527
+ prepareSync(esSyncSource, &oSrcID);
528
+
529
+ if ( isContinueSync() )
530
+ {
531
+ CSyncSource* pSrc = findSource(oSrcID);
532
+ if ( pSrc != null )
533
+ {
534
+ CSyncSource& src = *pSrc;
535
+ LOG(INFO) +"Started synchronization of the data source: " + src.getName();
536
+ src.m_strQueryParams = strQueryParams;
537
+ src.sync();
538
+
539
+ getNotify().fireSyncNotification(&src, true, src.m_nErrCode, src.m_nErrCode == RhoAppAdapter.ERR_NONE ? RhoAppAdapter.getMessageText("sync_completed") : "");
540
+ }else
541
+ {
542
+ LOG(ERROR) + "Sync one source : Unknown Source " + oSrcID.toString();
543
+
544
+ CSyncSource src(*this, getUserDB() );
545
+ //src.m_strError = "Unknown sync source.";
546
+ src.m_nErrCode = RhoAppAdapter.ERR_RUNTIME;
547
+
548
+ getNotify().fireSyncNotification(&src, true, src.m_nErrCode, "");
549
+ }
550
+ }
551
+
552
+ getNotify().cleanCreateObjectErrors();
553
+
554
+ if ( getState() != esExit )
555
+ setState(esNone);
556
+ }
557
+
558
+ CSyncSource* CSyncEngine::findSource(const CSourceID& oSrcID)
559
+ {
560
+ for( int i = 0; i < (int)m_sources.size(); i++ )
561
+ {
562
+ CSyncSource& src = *m_sources.elementAt(i);
563
+ if ( oSrcID.isEqual(src) )
564
+ return &src;
565
+ }
566
+
567
+ return null;
568
+ }
569
+
570
+ CSyncSource* CSyncEngine::findSourceByName(const String& strSrcName)
571
+ {
572
+ return findSource(CSourceID(strSrcName));
573
+ }
574
+
575
+ CSyncSource* CSyncEngine::findSourceById(int srcId)
576
+ {
577
+ for( int i = 0; i < (int)m_sources.size(); i++ )
578
+ {
579
+ CSyncSource& src = *m_sources.elementAt(i);
580
+ if ( src.getID() == srcId )
581
+ return &src;
582
+ }
583
+
584
+ return null;
585
+ }
586
+
587
+
588
+ void CSyncEngine::applyChangedValues(db::CDBAdapter& db)
589
+ {
590
+ IDBResult resSrc = db.executeSQL( "SELECT DISTINCT(source_id) FROM changed_values" );
591
+ for ( ; !resSrc.isEnd(); resSrc.next() )
592
+ {
593
+ int nSrcID = resSrc.getIntByIdx(0);
594
+ IDBResult res = db.executeSQL("SELECT source_id,sync_type,name, partition from sources WHERE source_id=?", nSrcID);
595
+ if ( res.isEnd() )
596
+ continue;
597
+
598
+ CSyncSource src( res.getIntByIdx(0), res.getStringByIdx(2), "none", db, *this );
599
+
600
+ src.applyChangedValues();
601
+ }
602
+ }
603
+
604
+ void CSyncEngine::loadAllSources()
605
+ {
606
+ if (rho_ruby_is_started())
607
+ {
608
+ if (isNoThreadedMode())
609
+ RhoAppAdapter.loadAllSyncSources();
610
+ else
611
+ {
612
+ NetResponse resp = getNet().pushData( getNet().resolveUrl("/system/loadallsyncsources"), "", null );
613
+ }
614
+ }else
615
+ RhoAppAdapter.loadAllSyncSources();
616
+
617
+ m_sources.removeAllElements();
618
+
619
+ Vector<String> arPartNames = db::CDBAdapter::getDBAllPartitionNames();
620
+
621
+ for( int i = 0; i < (int)arPartNames.size(); i++ )
622
+ {
623
+ db::CDBAdapter& dbPart = db::CDBAdapter::getDB(arPartNames.elementAt(i).c_str());
624
+ IDBResult res = dbPart.executeSQL("SELECT source_id,sync_type,name,source_attribs from sources ORDER BY sync_priority");
625
+ for ( ; !res.isEnd(); res.next() )
626
+ {
627
+ String strShouldSync = res.getStringByIdx(1);
628
+ if ( strShouldSync.compare("none") == 0 )
629
+ continue;
630
+
631
+ // TODO: the same for :full_update option
632
+ String strAttribs = res.getStringByIdx(3);
633
+ if (strAttribs.compare("pass_through") == 0) {
634
+ LOG(INFO) + "CSyncEngine::loadAllSources: enable pass_through property";
635
+ getSourceOptions().setProperty(res.getIntByIdx(0), "pass_through", "true");
636
+ }
637
+
638
+ String strName = res.getStringByIdx(2);
639
+
640
+ m_sources.addElement( new CSyncSource( res.getIntByIdx(0), strName, strShouldSync, dbPart, *this) );
641
+ }
642
+ }
643
+
644
+ checkSourceAssociations();
645
+ }
646
+
647
+ static int findSrcIndex( VectorPtr<CSyncSource*>& sources, const String& strSrcName)
648
+ {
649
+ for ( int i = 0; i < (int)sources.size(); i++)
650
+ {
651
+ if (strSrcName.compare(sources.elementAt(i)->getName()) == 0 )
652
+ return i;
653
+ }
654
+
655
+ return -1;
656
+ }
657
+
658
+ void CSyncEngine::checkSourceAssociations()
659
+ {
660
+ Hashtable<String, int> hashPassed;
661
+
662
+ for( int nCurSrc = m_sources.size()-1; nCurSrc >= 0 ; )
663
+ {
664
+ CSyncSource& oCurSrc = *(m_sources.elementAt(nCurSrc));
665
+ if ( oCurSrc.getAssociations().size() == 0 || hashPassed.containsKey(oCurSrc.getName()) )
666
+ nCurSrc--;
667
+ else
668
+ {
669
+ int nSrc = nCurSrc;
670
+ for( int i = 0; i < (int)oCurSrc.getAssociations().size(); i++ )
671
+ {
672
+ const CSyncSource::CAssociation& oAssoc = oCurSrc.getAssociations().elementAt(i);
673
+ int nAssocSrcIndex = findSrcIndex( m_sources, oAssoc.m_strSrcName);
674
+ if ( nAssocSrcIndex >= 0 )
675
+ m_sources.elementAt(nAssocSrcIndex)->addBelongsTo( oAssoc.m_strAttrib, oCurSrc.getID() );
676
+
677
+ if ( nAssocSrcIndex >=0 && nAssocSrcIndex < nSrc )
678
+ {
679
+ m_sources.removeElementAt( nSrc, false );
680
+ m_sources.insertElementAt( &oCurSrc, nAssocSrcIndex );
681
+
682
+ nSrc = nAssocSrcIndex;
683
+ }
684
+ }
685
+ }
686
+
687
+ hashPassed.put(oCurSrc.getName(), 1);
688
+ }
689
+ }
690
+
691
+ String CSyncEngine::readClientID()
692
+ {
693
+ String clientID = "";
694
+ synchronized(m_mxLoadClientID)
695
+ {
696
+ IDBResult res = getUserDB().executeSQL("SELECT client_id,reset from client_info limit 1");
697
+ if ( !res.isEnd() )
698
+ clientID = res.getStringByIdx(0);
699
+ }
700
+
701
+ return clientID;
702
+ }
703
+
704
+ String CSyncEngine::loadClientID()
705
+ {
706
+ String clientID = "";
707
+ synchronized(m_mxLoadClientID)
708
+ {
709
+ boolean bResetClient = false;
710
+ {
711
+ IDBResult res = getUserDB().executeSQL("SELECT client_id,reset from client_info limit 1");
712
+ if ( !res.isEnd() )
713
+ {
714
+ clientID = res.getStringByIdx(0);
715
+ bResetClient = res.getIntByIdx(1) > 0;
716
+ }
717
+ }
718
+
719
+ if ( clientID.length() == 0 )
720
+ {
721
+ clientID = requestClientIDByNet();
722
+
723
+ IDBResult res = getUserDB().executeSQL("SELECT * FROM client_info");
724
+ if ( !res.isEnd() )
725
+ getUserDB().executeSQL("UPDATE client_info SET client_id=?", clientID);
726
+ else
727
+ getUserDB().executeSQL("INSERT INTO client_info (client_id) values (?)", clientID);
728
+
729
+ }else if ( bResetClient )
730
+ {
731
+ if ( !resetClientIDByNet(clientID) )
732
+ stopSync();
733
+ else
734
+ getUserDB().executeSQL("UPDATE client_info SET reset=? where client_id=?", 0, clientID );
735
+ }
736
+ }
737
+
738
+ return clientID;
739
+ }
740
+
741
+ void CSyncEngine::processServerSources(String strSources)
742
+ {
743
+ if ( strSources.length() > 0 )
744
+ {
745
+ if (rho_ruby_is_started())
746
+ {
747
+ if (isNoThreadedMode())
748
+ RhoAppAdapter.loadServerSources(strSources);
749
+ else
750
+ {
751
+ NetResponse resp = getNet().pushData( getNet().resolveUrl("/system/loadserversources"), strSources, null );
752
+ }
753
+ }else
754
+ RhoAppAdapter.loadServerSources(strSources);
755
+
756
+ loadAllSources();
757
+
758
+ rho_db_init_attr_manager();
759
+ }
760
+ }
761
+
762
+ boolean CSyncEngine::resetClientIDByNet(const String& strClientID)//throws Exception
763
+ {
764
+ NetResponse resp = getNetClientID().doRequest(getProtocol().getClientResetMethod(),
765
+ getProtocol().getClientResetUrl(strClientID), getProtocol().getClientResetBody(), this, null );
766
+ if ( !resp.isOK() )
767
+ {
768
+ m_nErrCode = RhoAppAdapter.getErrorFromResponse(resp);
769
+ m_strError = resp.getCharData();
770
+ }else
771
+ RHOCONF().setString("reset_models", "", true);
772
+
773
+ return resp.isOK();
774
+ }
775
+
776
+ String CSyncEngine::requestClientIDByNet()
777
+ {
778
+ String clientCreateBody;
779
+ NetResponse resp = getNetClientID().doRequest(getProtocol().getClientCreateMethod(),
780
+ getProtocol().getClientCreateUrl(), "", this, null);
781
+ if ( resp.isOK() && resp.getCharData() != null )
782
+ {
783
+ const char* szData = resp.getCharData();
784
+
785
+ CJSONEntry oJsonEntry(szData);
786
+
787
+ CJSONEntry oJsonObject = oJsonEntry.getEntry("client");
788
+ if ( !oJsonObject.isEmpty() )
789
+ return oJsonObject.getString("client_id");
790
+ }else
791
+ {
792
+ m_nErrCode = RhoAppAdapter.getErrorFromResponse(resp);
793
+ m_strError = resp.getCharData();
794
+
795
+ if ( m_nErrCode == RhoAppAdapter.ERR_NONE )
796
+ m_nErrCode = RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE;
797
+ }
798
+
799
+ return "";
800
+ }
801
+
802
+ void CSyncEngine::doBulkSync()//throws Exception
803
+ {
804
+ // processServerSources(String("{\"partition\":\"") + "application" + "\"}");
805
+
806
+ if ( !RHOCONF().isExist(RHO_SETTING_BULKSYNC_STATE) )
807
+ return;
808
+
809
+ int nBulkSyncState = RHOCONF().getInt(RHO_SETTING_BULKSYNC_STATE);
810
+ if ( !isContinueSync() ) {
811
+ return;
812
+ }
813
+
814
+ switch (nBulkSyncState) {
815
+ case ebsNotSynced:
816
+ loadBulkPartitions();
817
+
818
+ if ( !isContinueSync() ) {
819
+ return;
820
+ }
821
+
822
+ //no break here is intentional.
823
+ case ebsLoadBlobs:
824
+ if ( !processBlobs() ) {
825
+ return;
826
+ }
827
+ break;
828
+
829
+ default:
830
+ return;
831
+ }
832
+
833
+ if (isContinueSync())
834
+ {
835
+ RHOCONF().setInt(RHO_SETTING_BULKSYNC_STATE, ebsSynced, true);
836
+ getNotify().fireBulkSyncNotification(true, "complete", "", RhoAppAdapter.ERR_NONE);
837
+ }
838
+ }
839
+
840
+ void CSyncEngine::loadBulkPartitions() {
841
+ LOG(INFO) + "Bulk sync: start";
842
+ getNotify().fireBulkSyncNotification(false, "start", "", RhoAppAdapter.ERR_NONE);
843
+ Vector<String> arPartNames = db::CDBAdapter::getDBAllPartitionNames();
844
+
845
+ for (int i = 0; i < (int)arPartNames.size() && isContinueSync(); i++)
846
+ {
847
+ if ( arPartNames.elementAt(i).compare("local") !=0 )
848
+ loadBulkPartition(arPartNames.elementAt(i));
849
+ }
850
+ }
851
+
852
+ boolean CSyncEngine::processBlobs() {
853
+ LOG(INFO) + "Bulk sync: download BLOBs";
854
+
855
+ RHOCONF().setInt(RHO_SETTING_BULKSYNC_STATE, ebsLoadBlobs, true );
856
+ getNotify().fireBulkSyncNotification( false, "blobs", "", RhoAppAdapter.ERR_NONE);
857
+
858
+ LOG(TRACE) + "=== Processing server blob attributes ===";
859
+
860
+ for ( int i = 0; i < (int)m_sources.size(); ++i ) {
861
+ CSyncSource& src = *m_sources.elementAt(i);
862
+ if ( !src.processServerBlobAttrs() ) {
863
+ getNotify().fireBulkSyncNotification(false, "error", "", RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE);
864
+ return false;
865
+ }
866
+ }
867
+
868
+ LOG(TRACE) + "=== Processing server blob attributes DONE ===";
869
+
870
+ rho_db_init_attr_manager();
871
+
872
+ for ( int i = 0; i < (int)m_sources.size(); ++i ) {
873
+ CSyncSource& src = *m_sources.elementAt(i);
874
+ if (!src.processAllBlobs()) {
875
+ getNotify().fireBulkSyncNotification(false, "error", "", RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE);
876
+ return false;
877
+ }
878
+ }
879
+
880
+ return true;
881
+ }
882
+
883
+
884
+ extern "C" int rho_sys_unzip_file(const char* szZipPath, const char* psw);
885
+
886
+ static String getHostFromUrl( const String& strUrl );
887
+ void CSyncEngine::loadBulkPartition(const String& strPartition )
888
+ {
889
+ db::CDBAdapter& dbPartition = getDB(strPartition);
890
+
891
+ Vector<String> source_names;
892
+ for ( int i = 0; i < (int)m_sources.size(); ++i ) {
893
+ source_names.push_back(m_sources[i]->getName());
894
+ }
895
+
896
+ String serverUrl = RHOCONF().getPath("syncserver");
897
+ String strUrl = getProtocol().getServerBulkDataUrl(getClientID(), strPartition, source_names);
898
+ String strBody = getProtocol().getServerBulkDataBody(strPartition, source_names);
899
+ String strDataUrl = "", strCmd = "", strCryptKey = "";
900
+
901
+ getNotify().fireBulkSyncNotification(false, "start", strPartition, RhoAppAdapter.ERR_NONE);
902
+
903
+ while(strCmd.length() == 0&&isContinueSync())
904
+ {
905
+ Hashtable<String, String> reqHeaders;
906
+ reqHeaders.put(getProtocol().getClientIDHeader(), getClientID());
907
+ NetResponse resp = getNet().doRequest(getProtocol().getServerBulkDataMethod(), strUrl, strBody, this, &reqHeaders);
908
+ const char* szData = resp.getCharData();
909
+ if ( !resp.isOK() || szData == null || *szData == 0)
910
+ {
911
+ LOG(ERROR) + "Bulk sync failed: server return an error.";
912
+ stopSync();
913
+ getNotify().fireBulkSyncNotification(true, "", strPartition, RhoAppAdapter.getErrorFromResponse(resp));
914
+ return;
915
+ }
916
+
917
+ LOG(INFO) + "Bulk sync: got response from server: " + szData;
918
+
919
+ CJSONEntry oJsonEntry(szData);
920
+ strCmd = oJsonEntry.getString("result");
921
+ if ( oJsonEntry.hasName("url") )
922
+ strDataUrl = oJsonEntry.getString("url");
923
+
924
+ if ( strCmd.compare("wait") == 0)
925
+ {
926
+ int nTimeout = RHOCONF().getInt("bulksync_timeout_sec");
927
+ if ( nTimeout == 0 )
928
+ nTimeout = 5;
929
+
930
+ CSyncThread::getInstance()->wait(nTimeout*1000);
931
+ strCmd = "";
932
+ }
933
+ }
934
+
935
+ if ( strCmd.compare("nop") == 0)
936
+ {
937
+ LOG(INFO) + "Bulk sync return no data.";
938
+ getNotify().fireBulkSyncNotification(true, "ok", strPartition, RhoAppAdapter.ERR_NONE);
939
+
940
+ return;
941
+ }
942
+
943
+ if ( !isContinueSync() )
944
+ return;
945
+
946
+ getNotify().fireBulkSyncNotification(false, "download", strPartition, RhoAppAdapter.ERR_NONE);
947
+
948
+ String fDataName = makeBulkDataFileName(strDataUrl, dbPartition.getDBPath(), "");
949
+ String strZip = ".rzip";
950
+ String strSqlDataUrl = CFilePath::join(getHostFromUrl(serverUrl), strDataUrl) +strZip;
951
+ LOG(INFO) + "Bulk sync: download data from server: " + strSqlDataUrl;
952
+ {
953
+ NetResponse resp1 = getNet().pullFile(strSqlDataUrl, fDataName+strZip, this, null, true, false);
954
+ if ( !resp1.isOK() )
955
+ {
956
+ LOG(ERROR) + "Bulk sync failed: cannot download database file.";
957
+ stopSync();
958
+ getNotify().fireBulkSyncNotification(true, "", strPartition, RhoAppAdapter.getErrorFromResponse(resp1));
959
+ return;
960
+ }
961
+ }
962
+
963
+ if ( !isContinueSync() )
964
+ return;
965
+
966
+ LOG(INFO) + "Bulk sync: unzip db";
967
+
968
+ if ( !rho_sys_unzip_file((fDataName+strZip).c_str(), ""), 0 )
969
+ {
970
+ CRhoFile::deleteFile((fDataName+strZip).c_str());
971
+ LOG(ERROR) + "Bulk sync failed: cannot unzip database file.";
972
+ stopSync();
973
+ getNotify().fireBulkSyncNotification(true, "", strPartition, RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE);
974
+ return;
975
+ }
976
+ CRhoFile::deleteFile((fDataName+strZip).c_str());
977
+
978
+ LOG(INFO) + "Bulk sync: start change db";
979
+ getNotify().fireBulkSyncNotification(false, "change_db", strPartition, RhoAppAdapter.ERR_NONE);
980
+
981
+ dbPartition.setBulkSyncDB(fDataName, strCryptKey);
982
+ getSourceOptions().clearProperties();
983
+ processServerSources(String("{\"partition\":\"") + strPartition + "\"}");
984
+
985
+ LOG(INFO) + "Bulk sync: end change db";
986
+ getNotify().fireBulkSyncNotification(false, "ok", strPartition, RhoAppAdapter.ERR_NONE);
987
+ }
988
+
989
+ String CSyncEngine::makeBulkDataFileName(String strDataUrl, String strDbPath, String strExt)
990
+ {
991
+ CFilePath oUrlPath(strDataUrl);
992
+ String strNewName = oUrlPath.getBaseName();
993
+
994
+ String strOldName = RHOCONF().getString("bulksync_filename");
995
+
996
+ if ( strOldName.length() > 0 && strNewName.compare(strOldName) != 0 )
997
+ {
998
+ CFilePath oFilePath(strDbPath);
999
+ String strFToDelete = oFilePath.changeBaseName(strOldName+strExt);
1000
+ LOG(INFO) + "Bulk sync: remove old bulk file '" + strFToDelete + "'";
1001
+
1002
+ CRhoFile::deleteFile( strFToDelete.c_str() );
1003
+ }
1004
+
1005
+ RHOCONF().setString("bulksync_filename", strNewName, true);
1006
+
1007
+ CFilePath oFilePath(strDbPath);
1008
+ return oFilePath.changeBaseName(strNewName+strExt);
1009
+ }
1010
+ /*
1011
+ int CSyncEngine::getStartSource()
1012
+ {
1013
+ for( int i = 0; i < (int)m_sources.size(); i++ )
1014
+ {
1015
+ CSyncSource& src = *m_sources.elementAt(i);
1016
+ if ( !src.isEmptyToken() )
1017
+ return i;
1018
+ }
1019
+
1020
+ return -1;
1021
+ }*/
1022
+
1023
+ void CSyncEngine::syncOneSource(int i, const String& strQueryParams, boolean syncOnlyIfChanged)
1024
+ {
1025
+ CSyncSource& src = *m_sources.elementAt(i);
1026
+ if ( src.getSyncType().compare("bulk_sync_only")==0 )
1027
+ return;
1028
+
1029
+ if ( isSessionExist() && getState() != esStop )
1030
+ {
1031
+ src.m_strQueryParams = strQueryParams;
1032
+ if (syncOnlyIfChanged) {
1033
+ if (src.haveChangedValues() ) {
1034
+ src.sync();
1035
+ }
1036
+ } else {
1037
+ src.sync();
1038
+ }
1039
+ }
1040
+
1041
+ getNotify().onSyncSourceEnd(i, m_sources);
1042
+
1043
+ // return src.m_nErrCode == RhoAppAdapter.ERR_NONE;
1044
+ }
1045
+
1046
+ void CSyncEngine::syncAllSources(const String& strQueryParams, boolean bSyncOnlyChangedSources)
1047
+ {
1048
+ // boolean bError = false;
1049
+
1050
+ // int nStartSrc = getStartSource();
1051
+ // if ( nStartSrc >= 0 )
1052
+ // bError = !syncOneSource(nStartSrc);
1053
+
1054
+ for( int i = 0; i < (int)m_sources.size() && isContinueSync(); i++ )
1055
+ {
1056
+ /*bError = !*/syncOneSource(i, strQueryParams, bSyncOnlyChangedSources);
1057
+ }
1058
+
1059
+ if ( !isSchemaChanged() && getState() != CSyncEngine::esStop )
1060
+ getNotify().fireSyncNotification(null, true, RhoAppAdapter.ERR_NONE, RhoAppAdapter.getMessageText("sync_completed"));
1061
+ }
1062
+
1063
+ void CSyncEngine::login(String name, String password, const CSyncNotification& oNotify)
1064
+ {
1065
+ // processServerSources("{\"sources\":{ \"Product\":{}, \"Customer\":{}}}");
1066
+ /*
1067
+ processServerSources(
1068
+ "{\"sources\":{ \"ProductEx\":{ "
1069
+ "\"sync_type\":\"incremental\", \"partition\":\"application\", \"source_id\":\"7\","
1070
+ " \"sync_priority\":\"0\", \"model_type\":\"fixed_schema\", "
1071
+ " \"schema\":{\"version\":\"1.1\", \"property\":{\"brand\":\"string\", \"price\":\"string\", \"quantity\":\"string\", \"name\":\"string\", "
1072
+ " \"image_url\":\"blob\", \"image_url_ex\":\"blob,overwrite\"}, "
1073
+ " \"index\":[{\"by_brand_price1\":\"brand,price\"}, {\"by_quantity1\":\"quantity\"}], \"unique_index\":[{\"by_name1\":\"name\"}]}, "
1074
+ " \"belongs_to\":{\"brand\":\"Customer\"}}}}");//, \"schema_version\":\"1.0\"
1075
+ */
1076
+ PROF_START("Login");
1077
+ m_bStopByUser = false;
1078
+ //try {
1079
+ loadAllSources();
1080
+
1081
+ NetResponse resp = getNet().pullCookies( getProtocol().getLoginUrl(), getProtocol().getLoginBody(name, password), this );
1082
+ int nErrCode = RhoAppAdapter.getErrorFromResponse(resp);
1083
+ if ( nErrCode != RhoAppAdapter.ERR_NONE )
1084
+ {
1085
+ getNotify().callLoginCallback(oNotify, nErrCode, resp.getCharData());
1086
+ return;
1087
+ }
1088
+
1089
+ String strSession = resp.getCharData();
1090
+ if ( strSession.length() == 0 )
1091
+ {
1092
+ LOG(ERROR) + "Return empty session.";
1093
+ getNotify().callLoginCallback(oNotify, RhoAppAdapter.ERR_UNEXPECTEDSERVERRESPONSE, "" );
1094
+ return;
1095
+ }
1096
+
1097
+ if ( isStoppedByUser() )
1098
+ {
1099
+ LOG(INFO) + "Login was stopped by application.";
1100
+ return;
1101
+ }
1102
+
1103
+ {
1104
+ IDBResult res = getUserDB().executeSQL("SELECT * FROM client_info");
1105
+ if ( !res.isEnd() )
1106
+ getUserDB().executeSQL( "UPDATE client_info SET session=?", strSession );
1107
+ else
1108
+ getUserDB().executeSQL("INSERT INTO client_info (session) values (?)", strSession);
1109
+ }
1110
+
1111
+ if ( RHOCONF().isExist("rho_sync_user") )
1112
+ {
1113
+ String strOldUser = RHOCONF().getString("rho_sync_user");
1114
+ if ( name.compare(strOldUser) != 0 )
1115
+ {
1116
+ if ( !RhoAppAdapter.callCallbackOnSyncUserChanged())
1117
+ {
1118
+ if (rho_ruby_is_started())
1119
+ {
1120
+ if (isNoThreadedMode())
1121
+ RhoAppAdapter.resetDBOnSyncUserChanged();
1122
+ else
1123
+ {
1124
+ NetResponse resp = getNet().pushData( getNet().resolveUrl("/system/resetDBOnSyncUserChanged"), "", null );
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ }
1130
+ RHOCONF().setString("rho_sync_user", name, true);
1131
+
1132
+ getNotify().callLoginCallback(oNotify, RhoAppAdapter.ERR_NONE, "" );
1133
+
1134
+ PROF_STOP("Login");
1135
+
1136
+ getUserDB().executeSQL("UPDATE client_info SET token_sent=?", 0 );
1137
+ CClientRegister::Get()->setRhoconnectCredentials(name, password, strSession);
1138
+
1139
+ //}catch(Exception exc)
1140
+ //{
1141
+ // LOG.ERROR("Login failed.", exc);
1142
+ // callLoginCallback(callback, RhoAppAdapter.ERR_RUNTIME, exc.getMessage() );
1143
+ //}
1144
+ }
1145
+
1146
+ boolean CSyncEngine::isLoggedIn()
1147
+ {
1148
+ String strRes = "";
1149
+ IDBResult res = getUserDB().executeSQL("SELECT session FROM client_info");
1150
+ if ( !res.isOneEnd() )
1151
+ strRes = res.getStringByIdx(0);
1152
+
1153
+ return strRes.length() > 0;
1154
+ }
1155
+
1156
+ String CSyncEngine::loadSession()
1157
+ {
1158
+ synchronized(m_mxSessionID)
1159
+ {
1160
+ m_strSession = "";
1161
+ IDBResult res = getUserDB().executeSQL("SELECT session FROM client_info");
1162
+
1163
+ if ( !res.isEnd() )
1164
+ m_strSession = res.getStringByIdx(0);
1165
+
1166
+ return m_strSession;
1167
+ }
1168
+ }
1169
+
1170
+ void CSyncEngine::logout_int()
1171
+ {
1172
+ CClientRegister::Get()->dropRhoconnectCredentials(m_strSession,getClientID());
1173
+ //CClientRegister::Destroy();
1174
+
1175
+ getUserDB().executeSQL( "UPDATE client_info SET session=NULL" );
1176
+ m_strSession = "";
1177
+
1178
+ //loadAllSources();
1179
+ }
1180
+
1181
+ void CSyncEngine::logout()
1182
+ {
1183
+ stopSync();
1184
+ logout_int();
1185
+ }
1186
+
1187
+ void CSyncEngine::setSyncServer(const char* syncserver)
1188
+ {
1189
+ String strOldSrv = RHOCONF().getString("syncserver");
1190
+ String strNewSrv = syncserver ? syncserver : "";
1191
+
1192
+ if ( strOldSrv.compare(strNewSrv) != 0)
1193
+ {
1194
+ RHOCONF().setString("syncserver", syncserver, true);
1195
+
1196
+ getUserDB().executeSQL("DELETE FROM client_info");
1197
+
1198
+ logout_int();
1199
+ }
1200
+ }
1201
+
1202
+ String CSyncEngine::getSyncServer() const {
1203
+ return RHOCONF().getString("syncserver");
1204
+ }
1205
+
1206
+
1207
+ static String getHostFromUrl( const String& strUrl )
1208
+ {
1209
+ const char* url = strUrl.c_str();
1210
+ const char* pStartSrv, *pEndSrv;
1211
+ int nSrvLen;
1212
+ const char* pHttp = strstr(url,"://");
1213
+ if ( !pHttp )
1214
+ pHttp = strstr(url,":\\\\");
1215
+
1216
+ if ( pHttp )
1217
+ pStartSrv = pHttp+3;
1218
+ else
1219
+ pStartSrv = url;
1220
+
1221
+ pEndSrv = strchr( pStartSrv, '/');
1222
+ if ( !pEndSrv )
1223
+ pEndSrv = strchr( pStartSrv, '\\');
1224
+
1225
+ nSrvLen = pEndSrv ? (pEndSrv+1 - url) : strlen(url);
1226
+ return String(url, nSrvLen);
1227
+ }
1228
+
1229
+ String CSyncEngine::CSourceID::toString()const
1230
+ {
1231
+ if ( m_strName.length() > 0 )
1232
+ return "name : " + m_strName;
1233
+
1234
+ return "# : " + convertToStringA(m_nID);
1235
+ }
1236
+
1237
+ boolean CSyncEngine::CSourceID::isEqual(CSyncSource& src)const
1238
+ {
1239
+ if ( m_strName.length() > 0 )
1240
+ return src.getName().compare(m_strName)==0;
1241
+
1242
+ return m_nID == src.getID();
1243
+ }
1244
+ }
1245
+ }