Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Source repo clean up

Change-Id: I13dcb1c53c3297c54eb7a72e640dd7c6922d86ca
  • Loading branch information...
commit 866c5f74a10a0133a097eccfea8c295a2c266684 0 parents
@qingbiao qingbiao authored
Showing with 27,756 additions and 0 deletions.
  1. +132 −0 README.md
  2. +8 −0 api/.gitignore
  3. +6 −0 api/CommonAPI/.classpath
  4. +17 −0 api/CommonAPI/.project
  5. +61 −0 api/CommonAPI/pom.xml
  6. +16 −0 api/CommonAPI/sharedglobal/1_constants.js
  7. +83 −0 api/CommonAPI/sharedglobal/2_blackberry_ns.js
  8. +186 −0 api/CommonAPI/sharedglobal/3_xhr.js
  9. +56 −0 api/CommonAPI/sharedglobal/4_events_ns.js
  10. +38 −0 api/CommonAPI/sharedglobal/5_blob.js
  11. +482 −0 api/CommonAPI/sharedglobal/json2.js
  12. +336 −0 api/CommonAPI/src/blackberry/common/push/PushDaemon.java
  13. +168 −0 api/CommonAPI/src/blackberry/common/push/PushData.java
  14. +134 −0 api/CommonAPI/src/blackberry/common/push/PushPersistentStore.java
  15. +50 −0 api/CommonAPI/src/blackberry/common/settings/SettingsManager.java
  16. +31 −0 api/CommonAPI/src/blackberry/common/settings/SettingsStoreFactory.java
  17. +67 −0 api/CommonAPI/src/blackberry/common/util/FeaturesHash.java
  18. +56 −0 api/CommonAPI/src/blackberry/common/util/ID.java
  19. +104 −0 api/CommonAPI/src/blackberry/common/util/JSUtilities.java
  20. +61 −0 api/CommonAPI/src/blackberry/common/util/PatternMatchingUtilities.java
  21. +75 −0 api/CommonAPI/src/blackberry/common/util/StringTokenizer.java
  22. +106 −0 api/CommonAPI/src/blackberry/common/util/StringUtilities.java
  23. +283 −0 api/CommonAPI/src/blackberry/common/util/URLDecoder.java
  24. +196 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSON.java
  25. +1,112 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONArray.java
  26. +107 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONArtifact.java
  27. +44 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONException.java
  28. +1,356 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONObject.java
  29. +21 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONString.java
  30. +47 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONStringer.java
  31. +575 −0 api/CommonAPI/src/blackberry/common/util/json4j/JSONWriter.java
  32. +11 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/JSON4JNumber.java
  33. +36 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/JSON4JPBackReader.java
  34. +43 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/JSON4JStringReader.java
  35. +45 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/JSON4JStringWriter.java
  36. +98 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/NumberUtil.java
  37. +332 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/Parser.java
  38. +342 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/Serializer.java
  39. +91 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/SerializerVerbose.java
  40. +104 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/Token.java
  41. +608 −0 api/CommonAPI/src/blackberry/common/util/json4j/internal/Tokenizer.java
  42. +60 −0 api/CommonAPI/src/blackberry/core/ApplicationEventHandler.java
  43. +142 −0 api/CommonAPI/src/blackberry/core/ApplicationRegistry.java
  44. +57 −0 api/CommonAPI/src/blackberry/core/Blob.java
  45. +132 −0 api/CommonAPI/src/blackberry/core/BlockingScriptableFunction.java
  46. +104 −0 api/CommonAPI/src/blackberry/core/EventService.java
  47. +121 −0 api/CommonAPI/src/blackberry/core/FunctionSignature.java
  48. +84 −0 api/CommonAPI/src/blackberry/core/IJSExtension.java
  49. +197 −0 api/CommonAPI/src/blackberry/core/JSExtensionRequest.java
  50. +110 −0 api/CommonAPI/src/blackberry/core/JSExtensionResponse.java
  51. +63 −0 api/CommonAPI/src/blackberry/core/JSExtensionReturnValue.java
  52. +174 −0 api/CommonAPI/src/blackberry/core/ObjectBase.java
  53. +252 −0 api/CommonAPI/src/blackberry/core/ScriptField.java
  54. +142 −0 api/CommonAPI/src/blackberry/core/ScriptableFunctionBase.java
  55. +118 −0 api/CommonAPI/src/blackberry/core/ScriptableFunctionWrapper.java
  56. +144 −0 api/CommonAPI/src/blackberry/core/ScriptableObjectBase.java
  57. +99 −0 api/CommonAPI/src/blackberry/core/ScriptableWrapper.java
  58. +232 −0 api/CommonAPI/src/blackberry/core/WidgetBlob.java
  59. +45 −0 api/CommonAPI/src/blackberry/core/WidgetProperties.java
  60. +57 −0 api/CommonAPI/src/blackberry/core/threading/CallbackDispatcherEvent.java
  61. +77 −0 api/CommonAPI/src/blackberry/core/threading/DispatchableEvent.java
  62. +60 −0 api/CommonAPI/src/blackberry/core/threading/Dispatcher.java
  63. +234 −0 api/CommonAPI/src/blackberry/core/threading/DispatcherImpl.java
  64. +34 −0 api/CommonAPI/src/blackberry/core/threading/GenericDispatcherEvent.java
  65. +285 −0 api/CommonAPI/src/blackberry/core/threading/InterruptibleThread.java
  66. +7 −0 api/app/.classpath
  67. +17 −0 api/app/.project
  68. +27 −0 api/app/doc/library.xml
  69. +110 −0 api/app/pom.xml
  70. +134 −0 api/app/src/main/java/blackberry/app/AppExtension.java
  71. +117 −0 api/app/src/main/java/blackberry/app/AppNamespace.java
  72. +41 −0 api/app/src/main/java/blackberry/app/ExitFunction.java
  73. +40 −0 api/app/src/main/java/blackberry/app/RemoveBannerIndicatorFunction.java
  74. +36 −0 api/app/src/main/java/blackberry/app/RequestBackgroundFunction.java
  75. +36 −0 api/app/src/main/java/blackberry/app/RequestForegroundFunction.java
  76. +113 −0 api/app/src/main/java/blackberry/app/SetHomeScreenIconFunction.java
  77. +45 −0 api/app/src/main/java/blackberry/app/SetHomeScreenNameFunction.java
  78. +78 −0 api/app/src/main/java/blackberry/app/ShowBannerIndicatorFunction.java
  79. +131 −0 api/app/src/main/java/blackberry/app/event/AppEventNamespace.java
  80. +7 −0 api/audio/.classpath
  81. +17 −0 api/audio/.project
  82. +28 −0 api/audio/doc/library.xml
  83. +110 −0 api/audio/pom.xml
  84. +70 −0 api/audio/src/main/java/blackberry/audio/AudioExtension.java
  85. +155 −0 api/audio/src/main/java/blackberry/audio/AudioNamespace.java
  86. +126 −0 api/audio/src/main/java/blackberry/audio/Player/PlayerConstructor.java
  87. +197 −0 api/audio/src/main/java/blackberry/audio/Player/PlayerController.java
  88. +180 −0 api/audio/src/main/java/blackberry/audio/Player/PlayerObject.java
  89. +100 −0 api/audio/src/main/java/blackberry/audio/PlayerListener/PlayerListenerController.java
  90. +63 −0 api/audio/src/main/java/blackberry/audio/PlayerListener/PlayerListenerObject.java
  91. +8 −0 api/bbm/.classpath
  92. +17 −0 api/bbm/.project
  93. +29 −0 api/bbm/doc/library.xml
  94. BIN  api/bbm/lib/net_rim_bb_qm_platform.jar
  95. +116 −0 api/bbm/pom.xml
  96. +82 −0 api/bbm/src/main/java/blackberry/bbm/platform/BBMPlatformContextListenerImpl.java
  97. +53 −0 api/bbm/src/main/java/blackberry/bbm/platform/BBMPlatformExtension.java
  98. +199 −0 api/bbm/src/main/java/blackberry/bbm/platform/BBMPlatformNamespace.java
  99. +60 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ChannelListener.java
  100. +50 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ChannelObject.java
  101. +146 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ConnectionListenerImpl.java
  102. +302 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ConnectionObject.java
  103. +345 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/IONamespace.java
  104. +233 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/MessagingServiceListenerImpl.java
  105. +89 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ScriptableIncomingJoinRequest.java
  106. +42 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ScriptableJoinRequest.java
  107. +69 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/ScriptableOutgoingJoinRequest.java
  108. +105 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/SessionListener.java
  109. +99 −0 api/bbm/src/main/java/blackberry/bbm/platform/io/SessionObject.java
  110. +201 −0 api/bbm/src/main/java/blackberry/bbm/platform/self/SelfNamespace.java
  111. +46 −0 api/bbm/src/main/java/blackberry/bbm/platform/self/location/LocationNamespace.java
  112. +171 −0 api/bbm/src/main/java/blackberry/bbm/platform/self/profilebox/ProfileBoxNamespace.java
  113. +75 −0 api/bbm/src/main/java/blackberry/bbm/platform/self/profilebox/ScriptableProfileBoxItem.java
  114. +42 −0 api/bbm/src/main/java/blackberry/bbm/platform/ui/UINamespace.java
  115. +139 −0 api/bbm/src/main/java/blackberry/bbm/platform/ui/menu/MenuNamespace.java
  116. +136 −0 api/bbm/src/main/java/blackberry/bbm/platform/users/BBMPlatformUser.java
  117. +507 −0 api/bbm/src/main/java/blackberry/bbm/platform/users/UsersNamespace.java
  118. +92 −0 api/bbm/src/main/java/blackberry/bbm/platform/util/ConstantsUtil.java
  119. +71 −0 api/bbm/src/main/java/blackberry/bbm/platform/util/ScriptableFieldManager.java
  120. +265 −0 api/bbm/src/main/java/blackberry/bbm/platform/util/Util.java
  121. +7 −0 api/dialog/.classpath
  122. +17 −0 api/dialog/.project
  123. +25 −0 api/dialog/doc/library.xml
  124. +110 −0 api/dialog/pom.xml
  125. +118 −0 api/dialog/src/main/java/blackberry/ui/dialog/CustomAskFunction.java
  126. +65 −0 api/dialog/src/main/java/blackberry/ui/dialog/DialogExtension.java
  127. +104 −0 api/dialog/src/main/java/blackberry/ui/dialog/DialogNamespace.java
  128. +102 −0 api/dialog/src/main/java/blackberry/ui/dialog/DialogRunner.java
  129. +116 −0 api/dialog/src/main/java/blackberry/ui/dialog/StandardAskFunction.java
  130. +7 −0 api/find/.classpath
  131. +17 −0 api/find/.project
  132. +26 −0 api/find/doc/library.xml
  133. +110 −0 api/find/pom.xml
  134. +372 −0 api/find/src/main/java/blackberry/find/ExpressionTester.java
  135. +81 −0 api/find/src/main/java/blackberry/find/FindExtension.java
  136. +395 −0 api/find/src/main/java/blackberry/find/FindNamespace.java
  137. +33 −0 api/find/src/main/java/blackberry/find/TestableScriptableObject.java
  138. +157 −0 api/find/src/main/java/blackberry/find/filterExpression/FilterExpressionConstructor.java
  139. +181 −0 api/find/src/main/java/blackberry/find/filterExpression/FilterExpressionObject.java
  140. +7 −0 api/identity/.classpath
  141. +17 −0 api/identity/.project
  142. +27 −0 api/identity/doc/library.xml
  143. +110 −0 api/identity/pom.xml
  144. +190 −0 api/identity/src/main/java/blackberry/identity/GetTransportListFunction.java
  145. +127 −0 api/identity/src/main/java/blackberry/identity/IdentityExtension.java
  146. +137 −0 api/identity/src/main/java/blackberry/identity/IdentityFunctions.java
  147. +81 −0 api/identity/src/main/java/blackberry/identity/IdentityNamespace.java
  148. +43 −0 api/identity/src/main/java/blackberry/identity/phone/GetLineIdsFunction.java
  149. +44 −0 api/identity/src/main/java/blackberry/identity/phone/GetLineLabelFunction.java
  150. +44 −0 api/identity/src/main/java/blackberry/identity/phone/GetLineNumberFunction.java
  151. +44 −0 api/identity/src/main/java/blackberry/identity/phone/GetLineTypeFunction.java
  152. +28 −0 api/identity/src/main/java/blackberry/identity/phone/PhoneFunctionBase.java
  153. +66 −0 api/identity/src/main/java/blackberry/identity/phone/PhoneNamespace.java
  154. +124 −0 api/identity/src/main/java/blackberry/identity/service/ServiceObject.java
  155. +69 −0 api/identity/src/main/java/blackberry/identity/transport/TransportObject.java
  156. +10 −0 api/invoke/.classpath
  157. +17 −0 api/invoke/.project
  158. +43 −0 api/invoke/doc/library.xml
  159. +130 −0 api/invoke/pom.xml
  160. +180 −0 api/invoke/src/main/java/blackberry/invoke/InvokeExtension.java
  161. +601 −0 api/invoke/src/main/java/blackberry/invoke/InvokeFunction.java
  162. +100 −0 api/invoke/src/main/java/blackberry/invoke/InvokeNamespace.java
  163. +80 −0 api/invoke/src/main/java/blackberry/invoke/addressBookArguments/AddressBookArgumentsConstructor.java
  164. +100 −0 api/invoke/src/main/java/blackberry/invoke/addressBookArguments/AddressBookArgumentsObject.java
  165. +58 −0 api/invoke/src/main/java/blackberry/invoke/browserArguments/BrowserArgumentsConstructor.java
  166. +92 −0 api/invoke/src/main/java/blackberry/invoke/browserArguments/BrowserArgumentsObject.java
  167. +126 −0 api/invoke/src/main/java/blackberry/invoke/calendarArguments/CalendarArgumentsConstructor.java
  168. +137 −0 api/invoke/src/main/java/blackberry/invoke/calendarArguments/CalendarArgumentsObject.java
  169. +62 −0 api/invoke/src/main/java/blackberry/invoke/cameraArguments/CameraArgumentsConstructor.java
  170. +61 −0 api/invoke/src/main/java/blackberry/invoke/cameraArguments/CameraArgumentsObject.java
  171. +77 −0 api/invoke/src/main/java/blackberry/invoke/javaArguments/JavaArgumentsConstructor.java
  172. +57 −0 api/invoke/src/main/java/blackberry/invoke/javaArguments/JavaArgumentsObject.java
  173. +100 −0 api/invoke/src/main/java/blackberry/invoke/mapsArguments/MapsArgumentsConstructor.java
  174. +155 −0 api/invoke/src/main/java/blackberry/invoke/mapsArguments/MapsArgumentsObject.java
  175. +78 −0 api/invoke/src/main/java/blackberry/invoke/memoArguments/MemoArgumentsConstructor.java
  176. +98 −0 api/invoke/src/main/java/blackberry/invoke/memoArguments/MemoArgumentsObject.java
  177. +119 −0 api/invoke/src/main/java/blackberry/invoke/messageArguments/MessageArgumentsConstructor.java
  178. +76 −0 api/invoke/src/main/java/blackberry/invoke/messageArguments/MessageArgumentsObject.java
  179. +92 −0 api/invoke/src/main/java/blackberry/invoke/phoneArguments/PhoneArgumentsConstructor.java
  180. +104 −0 api/invoke/src/main/java/blackberry/invoke/phoneArguments/PhoneArgumentsObject.java
  181. +57 −0 api/invoke/src/main/java/blackberry/invoke/searchArguments/SearchArgumentsConstructor.java
  182. +77 −0 api/invoke/src/main/java/blackberry/invoke/searchArguments/SearchArgumentsObject.java
  183. +76 −0 api/invoke/src/main/java/blackberry/invoke/taskArguments/TaskArgumentsConstructor.java
  184. +99 −0 api/invoke/src/main/java/blackberry/invoke/taskArguments/TaskArgumentsObject.java
  185. +7 −0 api/io/.classpath
  186. +17 −0 api/io/.project
  187. +25 −0 api/io/doc/library.xml
  188. +110 −0 api/io/pom.xml
  189. +189 −0 api/io/src/main/java/blackberry/io/FileConnectionWrapper.java
  190. +72 −0 api/io/src/main/java/blackberry/io/IOExtension.java
  191. +63 −0 api/io/src/main/java/blackberry/io/dir/CreateNewDirFunction.java
  192. +131 −0 api/io/src/main/java/blackberry/io/dir/DeleteDirectoryFunction.java
  193. +73 −0 api/io/src/main/java/blackberry/io/dir/DirNamespace.java
  194. +59 −0 api/io/src/main/java/blackberry/io/dir/ExistsFunction.java
  195. +60 −0 api/io/src/main/java/blackberry/io/dir/GetFreeSpaceForRootFunction.java
  196. +69 −0 api/io/src/main/java/blackberry/io/dir/GetParentDirectoryFunction.java
  197. +68 −0 api/io/src/main/java/blackberry/io/dir/GetRootDirsFunction.java
  198. +86 −0 api/io/src/main/java/blackberry/io/dir/ListDirectoriesFunction.java
  199. +83 −0 api/io/src/main/java/blackberry/io/dir/ListFilesFunction.java
  200. +72 −0 api/io/src/main/java/blackberry/io/dir/RenameFunction.java
  201. +89 −0 api/io/src/main/java/blackberry/io/file/CopyFunction.java
  202. +66 −0 api/io/src/main/java/blackberry/io/file/DeleteFileFunction.java
  203. +65 −0 api/io/src/main/java/blackberry/io/file/ExistsFunction.java
  204. +75 −0 api/io/src/main/java/blackberry/io/file/FileNamespace.java
  205. +107 −0 api/io/src/main/java/blackberry/io/file/FileProperties/FilePropertiesObject.java
  206. +131 −0 api/io/src/main/java/blackberry/io/file/GetFilePropertiesFunction.java
  207. +102 −0 api/io/src/main/java/blackberry/io/file/OpenFunction.java
  208. +139 −0 api/io/src/main/java/blackberry/io/file/ReadFileFunction.java
  209. +71 −0 api/io/src/main/java/blackberry/io/file/RenameFunction.java
  210. +72 −0 api/io/src/main/java/blackberry/io/file/SaveFileFunction.java
  211. +7 −0 api/media.camera/.classpath
  212. +17 −0 api/media.camera/.project
  213. +87 −0 api/media.camera/doc/library.xml
  214. +110 −0 api/media.camera/pom.xml
  215. +97 −0 api/media.camera/src/main/java/blackberry/media/JournalListener.java
  216. +115 −0 api/media.camera/src/main/java/blackberry/media/ProcessCheckThread.java
  217. +90 −0 api/media.camera/src/main/java/blackberry/media/camera/CameraExtension.java
  218. +55 −0 api/media.camera/src/main/java/blackberry/media/camera/CameraNamespace.java
  219. +53 −0 api/media.camera/src/main/java/blackberry/media/camera/CloseFunction.java
  220. +180 −0 api/media.camera/src/main/java/blackberry/media/camera/TakePictureFunction.java
  221. +214 −0 api/media.camera/src/main/java/blackberry/media/camera/TakeVideoFunction.java
  222. +7 −0 api/media.microphone/.classpath
  223. +17 −0 api/media.microphone/.project
  224. +33 −0 api/media.microphone/doc/library.xml
  225. +110 −0 api/media.microphone/pom.xml
  226. +38 −0 api/media.microphone/src/main/java/blackberry/media/microphone/GetSupportedMediaTypesFunction.java
  227. +89 −0 api/media.microphone/src/main/java/blackberry/media/microphone/MicrophoneExtension.java
  228. +67 −0 api/media.microphone/src/main/java/blackberry/media/microphone/MicrophoneNamespace.java
  229. +40 −0 api/media.microphone/src/main/java/blackberry/media/microphone/PauseFunction.java
  230. +281 −0 api/media.microphone/src/main/java/blackberry/media/microphone/Record.java
  231. +69 −0 api/media.microphone/src/main/java/blackberry/media/microphone/RecordFunction.java
  232. +40 −0 api/media.microphone/src/main/java/blackberry/media/microphone/StopFunction.java
  233. +7 −0 api/menu/.classpath
  234. +17 −0 api/menu/.project
  235. +24 −0 api/menu/doc/library.xml
  236. +110 −0 api/menu/pom.xml
  237. +59 −0 api/menu/src/main/java/blackberry/ui/menu/AddMenuItemFunction.java
  238. +50 −0 api/menu/src/main/java/blackberry/ui/menu/ClearMenuItemsFunction.java
  239. +34 −0 api/menu/src/main/java/blackberry/ui/menu/GetMenuItemsFunction.java
  240. +48 −0 api/menu/src/main/java/blackberry/ui/menu/HasMenuItemFunction.java
  241. +80 −0 api/menu/src/main/java/blackberry/ui/menu/MenuExtension.java
  242. +126 −0 api/menu/src/main/java/blackberry/ui/menu/MenuItemObjectManager.java
  243. +70 −0 api/menu/src/main/java/blackberry/ui/menu/MenuNamespace.java
  244. +54 −0 api/menu/src/main/java/blackberry/ui/menu/OpenFunction.java
  245. +51 −0 api/menu/src/main/java/blackberry/ui/menu/RemoveMenuItemFunction.java
  246. +61 −0 api/menu/src/main/java/blackberry/ui/menu/SetDefaultMenuItemFunction.java
  247. +62 −0 api/menu/src/main/java/blackberry/ui/menu/item/MenuItemConstructor.java
  248. +154 −0 api/menu/src/main/java/blackberry/ui/menu/item/MenuItemObject.java
  249. +7 −0 api/message/.classpath
  250. +17 −0 api/message/.project
  251. +24 −0 api/message/doc/library.xml
Sorry, we could not display the entire diff because too many files (466) changed.
132 README.md
@@ -0,0 +1,132 @@
+# About BlackBerry® WebWorks™
+
+The BlackBerry® WebWorks™ for the BlackBerry Smartphone OS allows web and mobile web developers to use the SDK in combination with their development
+tooling of choice to develop, test and package up their web applications as BlackBerry WebWorks applications for smartphones.
+BlackBerry WebWorks applications can be distributed through the BlackBerry App World™ storefront and they run on the BlackBerry® Smartphones
+with access to the hardware.
+
+The project is open source under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) license.
+
+* Advanced Standards
+* Powerful Integration
+* Open
+
+[Read more](http://blackberry.github.com) about the BlackBerry WebWorks open source project
+
+## Downloads
+Full installers for Windows and Mac OS X can be found on the [product download page](http://developer.blackberry.com/html5/download/sdk)
+
+## Reference Material & Community
+You can also find associated reference material for the BlackBerry WebWorks platform as well as community forums for building and contributing to the BlackBerry WebWorks project
+
+* [API Reference](http://developer.blackberry.com/html5/api)
+* [Installation and Developer Guides](http://developer.blackberry.com/html5/documentation)
+* [Community Forums](http://supportforums.blackberry.com/t5/Web-Development/bd-p/browser_dev)
+* [Project Contributor Forums](http://supportforums.blackberry.com/t5/BlackBerry-WebWorks/bd-p/ww_con)
+* [Open Source Project Contributor Forums](http://supportforums.blackberry.com/t5/BlackBerry-WebWorks/bd-p/ww_con)
+
+## Building the Source Code
+
+### Download and install Maven on Windows®
+Note: In order to build the source code you must have the [Java SE Development Kit v1.6](http://java.sun.com/javase/downloads/index.jsp#jdk) or higher installed
+
+1. The first step is to [Download Maven v3.0](http://maven.apache.org/download.html) and create an installation directory.
+2. On the Maven download page, select the _(Binary zip)_ format of the latest Maven v3.0 from the mirror of your choice.
+3. When the download is finished, take the file and unzip it to the "C:\Program Files\Apache Software Foundation" directory. If the directory does not exist create it.
+4. The second step is to add environment variables. From the start menu right click on "My Computer" and click on properties. If you are on Windows XP click the advanced tab then click on environment variables. If you arer using Windows 7 click on advanced systems settings then click on environment variables.
+5. To add the first environment variable, look under system variables, click on the new button and enter "M2_HOME" (without the quotes) for the variable name and enter the path to your maven installation directory for the variable value e.g. C:\Program Files\Apache Software Foundation\apache-maven-(your version number). Click ok when you're done.
+6. Add a second environment variable with "M2" for the name and "%M2_HOME%\bin" (without the quotes) as the value.
+7. If JAVA_HOME is not listed as one of the variables under System Variables then add a new environment variable with "JAVA_HOME" as the name and the path to you JDK installation directory (not the bin folder) as the value.
+8. Click on the Path variable and click edit. Then add the following string to the end of value for path:
+
+ "%JAVA_HOME%\bin;%M2%"
+
+9. Open up a command prompt and type "mvn --version". _NOTE: If you already had a command prompt open, close it and open a new one so that your changes are reflected._ You should see some information about your maven installation. If you get a prompt stating that the command was not found then you probably made a mistake in one of the previous steps.
+
+### Download and install maven on Mac OSX
+
+Note: In order to build the source code you must have the Java Development Kit version 1.6 installed.
+
+
+#### Using MacPorts
+It is recommended to install Maven on OSX using MacPorts. If you do not currently have MacPorts you can install it from http://www.macports.org/install.php.
+
+1. Run the following command:
+
+ sudo port install maven3
+
+2. Run mvn --version to vertify that it is correctly installed.
+
+If you do not wish to use MacPorts simply use the following instructions.
+
+#### Without using MacPorts
+1. Extract the distribution archive, i.e. apache-maven-3.0.3-bin.tar.gz to the directory you wish to install Maven 3.0.3. These instructions assume you chose /usr/local/apache-maven. The subdirectory apache-maven-3.0.3 will be created from the archive.
+2. In a command terminal, add the M2_HOME environment variable, e.g. export M2_HOME=/usr/local/apache-maven/apache-maven-3.0.3.
+3. Add the M2 environment variable, e.g. export M2=$M2_HOME/bin.
+4. Optional: Add the MAVEN_OPTS environment variable to specify JVM properties, e.g. export MAVEN_OPTS="-Xms256m -Xmx512m". This environment variable can be used to supply extra options to Maven.
+5. Add M2 environment variable to your path, e.g. export PATH=$M2:$PATH.
+6. Make sure that JAVA_HOME is set to the location of your JDK, e.g. export JAVA_HOME=/usr/java/jdk1.5.0_02 and that $JAVA_HOME/bin is in your PATH environment variable.
+7. Run mvn --version to verify that it is correctly installed.
+
+### Download and install gcc compiler on Windows®
+1. The first step is to download the automated installer for MinGW from
+[here.](http://sourceforge.net/projects/mingw/files/).
+2. After the installer has been downloaded run the installer. Follow the
+installation instructions in the installer and make sure you note the
+installation directory for MingGW which is C:\MinGW by default.
+3. When you have installed MinGW on your machine navigate to the
+environment variable settings as stated above when installing Maven on Windows.
+4. Find the Path environment variable and click the "Edit" button.
+5. Append ";(Path to MinGW)\bin" to the value of the environment varible e.g.
+if MinGW is installed at C:\MinGW then you should append ";C:\MinGW\bin" to the
+Path environment variable.
+
+### Download and install gcc compiler on Mac OS X
+
+#### Register for an Apple Developer Connection Account
+1. Navigate to [http://connect.apple.com](http://connect.apple.com). You will
+be taken to a page with a prompt for your Apple ID. Click the "Join Now" link.
+2. On the next page scroll down to the bottom of the page and click on the
+"Learn More" link. On the following page click on the "Get Started" link and
+follow the instructions for the Apple Developer Registration process.
+
+#### Download and Install XCode
+Once you're registered. Navigate to
+[http://connect.apple.com](http://connect.apple.com) and download the
+XCode Tools (Version) disk image file. Double click the file and
+follow the installations steps to complete the installation.
+
+### Build the project
+
+From command line, change to the root directory of the WebWorks repository and run the following commands:
+
+ mvn clean install -DPRODUCT_VERSION=[version]
+
+The version is the WebWorks version that you want to build (e.g. 2.3.0.1).
+The first time the build is run it will take up to 5 minutes to complete and will require an internet connection. Subsequent builds take around 2 minutes.
+
+If the build is successful two zip files will be generated in a "target" directory located in the root of the WebWorks repository.
+The Two zip files are "WebWorksForSmartphoneWin.zip" for Windows and "WebWorksForSmartphoneMac.zip" for Mac.
+
+
+## Patching an Existing WebWorks Installation
+
+1. Locate your existing WebWorks SDK installation. The default path is
+"C:\Program Files\Research In Motion\BlackBerry WebWorks SDK (Version)"
+for Windows and
+"/Developer/SDKs/Research In Motion/BlackBerry WebWorks SDK (Version)"
+for Mac.
+2. In your WebWorks installation directory backup and delete the following files/folders:
+ - "bbwp" executable file in root folder
+ - "bbwp.jar", "bbwp.properties", "tld.txt" in bin folder
+ - "device_templates" and "ext" folder
+3. The output of the build is stored in the target folder in the root
+directory. It contains two zip files, "WebWorksForSmartphoneWin.zip"
+for windows and "WebWorksForSmartphoneMac.zip" for Mac. Unzip the zip
+file for your platform into your installation directory.
+4. If you are using Windows, open up the backup "bin\bbwp.properties" file
+and copy the path located in the java element to the java element in the
+new "bin\bbwp.properties" file.
+5. You can now start building WebWorks applications with the patched SDK.
+
+
8 api/.gitignore
@@ -0,0 +1,8 @@
+*/build/
+*/bin/
+*/target/
+*/deliverables/
+*/.settings/
+/output/
+/target/
+/lib/
6 api/CommonAPI/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
17 api/CommonAPI/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>CommonAPI</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
61 api/CommonAPI/pom.xml
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- The Basics -->
+ <parent>
+ <groupId>net.rim.webworks</groupId>
+ <artifactId>api</artifactId>
+ <version>2.3.0.0</version>
+ </parent>
+
+ <artifactId>CommonAPI</artifactId>
+ <packaging>pom</packaging>
+
+ <properties>
+ <api.source>${basedir}/sharedglobal</api.source>
+ <api.docs>${basedir}/../../api-docs/blackberry/app</api.docs>
+ <api.output.folder>${basedir}/../output/common/sharedglobal</api.output.folder>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <echo>Copying sharedglobal file to api output folder</echo>
+ <copy todir="${api.output.folder}">
+ <fileset dir="${api.source}" includes="*/**" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.3.2-SNAPSHOT</version>
+ <configuration>
+ <threshold>Normal</threshold>
+ <xmlOutput>true</xmlOutput>
+ <findbugsXmlOutput>true</findbugsXmlOutput>
+ <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
16 api/CommonAPI/sharedglobal/1_constants.js
@@ -0,0 +1,16 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+var SERVER_URL = "http://localhost:8472/";
83 api/CommonAPI/sharedglobal/2_blackberry_ns.js
@@ -0,0 +1,83 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+(function () {
+ this.blackberry = {};
+
+ var WebWorksLoader = function() {
+ this.loadedJs = {}; //hash of literal namespace - javascript constructor (can be either API or dispatcher, whichever is loaded first)
+ }
+
+ var isDispatcher = function(func) {
+ return (typeof(func) == 'function' && func.name.search(/dispatcher/i) > -1);
+ }
+
+ /*
+ Called by each API/dispatcher when it has finished loading. If its pair has already been loaded, it instantiates the API. Otherwise
+ stores the current half of the API and waits for the other one to load before instantiating.
+ */
+ WebWorksLoader.prototype.javascriptLoaded = function(ns, js) {
+ //Check if the other half of the API has loaded
+ if(typeof this.loadedJs[ns] == 'function') {
+ var api, dispatcher;
+ //If the function just loaded is the dispatcher, the one we have is the API, and vice-versa
+ if(isDispatcher(js)) {
+ api = this.loadedJs[ns];
+ dispatcher = js;
+ } else {
+ api = js;
+ dispatcher = this.loadedJs[ns];
+ }
+
+ this.loadApi(ns, api, dispatcher);
+ delete this.loadedJs[ns]; //remove namespace entry to prevent double loading
+ } else {
+ //Otherwise queue up and wait for API to load
+ this.loadedJs[ns] = js;
+ }
+ }
+
+ /*
+ Instantiates the provided API constructor with the provided dispatcher and attaches
+ the result to the requested namespace.
+ */
+ WebWorksLoader.prototype.loadApi = function(namespace, apiConstructor, dispatcher) {
+ //Instantiate the API
+ var d = (typeof dispatcher != 'undefined') ? new dispatcher() : {};
+ var api = new apiConstructor(d);
+
+ //Break namespace into array of parts around the '.'
+ var nsParts = namespace.split('.');
+ //Must start with 'blackberry'
+ if(nsParts[0] != 'blackberry') {
+ throw new Error('Namespace does not start with blackberry:' + namespace);
+ }
+
+ //Iterate over remaining namespace parts and create the empty namespace if it does not exist.
+ //If it exists, just ignore it.
+ var ns = blackberry;
+ for(var i = 1; i < nsParts.length - 1; i++) {
+ if(typeof ns[nsParts[i]] == 'undefined') {
+ ns[nsParts[i]] = {};
+ }
+ ns = ns[nsParts[i]];
+ }
+
+ //Once namespace is built, attach the object to it
+ ns[nsParts[nsParts.length - 1]] = api;
+ }
+
+ this.blackberry.Loader = new WebWorksLoader();
+})();
186 api/CommonAPI/sharedglobal/3_xhr.js
@@ -0,0 +1,186 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+(function () {
+
+ var _frameworkReady = false;
+ var _deferredRequests = new Array();
+
+ function onFrameworkReady( e ) {
+ _frameworkReady = true;
+
+ for(var i = 0; i < _deferredRequests.length; i++) {
+ var item = _deferredRequests[i];
+ try {
+ item.request.send(item.postData);
+ } catch(e) {}
+ }
+
+ _deferredRequests = null;
+ window.removeEventListener("frameworkready", onFrameworkReady, false);
+ }
+
+ window.addEventListener("frameworkready", onFrameworkReady, false, true);
+
+ if(!this.blackberry) {
+ return;
+ }
+
+ this.blackberry.transport = {
+ "RemoteFunctionCall" : function(functionUri) {
+ /*
+ * Private members
+ */
+ var uri = functionUri;
+ var params = {};
+ var postParams = {};
+ var postData = null;
+
+ var composeUri = function() {
+ //SERVER_URL is defined in constants.js and is assumed to have already been attached
+ var uri = SERVER_URL + functionUri;
+
+ //If we have parameters, let's append them
+ var paramCount = 1;
+ for(param in params) {
+ if(params.hasOwnProperty(param)) {
+ //If it's not the first parameter, prepend the '&' separator
+ if(paramCount == 1) {
+ //start the query string with an '?'
+ uri += "?";
+ } else {
+ uri += "&";
+ }
+ uri += param + "=" + params[param];
+ paramCount++;
+ }
+ }
+
+ return uri;
+ };
+
+ var composePostData = function() {
+ for (param in postParams) {
+ if (postParams.hasOwnProperty(param)) {
+ if (!postData) {
+ postData = "";
+ } else {
+ postData += "&";
+ }
+
+ postData += param + "=" + postParams[param];
+ }
+ }
+ };
+
+ var createXhrRequest = function(uri, isAsync) {
+ var request = new XMLHttpRequest();
+
+ request.open("POST", uri, isAsync);
+ //request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ request.setRequestHeader("Accept", "*/*");
+ request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ return request;
+ };
+
+ /*
+ * Public members
+ */
+ this.addParam = function(name, value) {
+ params[name] = encodeURIComponent(value);
+ };
+
+ this.addPostParam = function(name, value) {
+ postParams[name] = encodeURIComponent(value);
+ };
+
+ this.makeSyncCall = function(jsonReviver) {
+ var requestUri = composeUri();
+ var request = createXhrRequest(requestUri, false);
+
+ composePostData();
+
+ try {
+ request.send(postData);
+ } catch(e) {}
+ //alert(request.responseText);
+ return JSON.parse(request.responseText, jsonReviver); //retrieve result encoded as JSON
+ };
+
+ this.makeAsyncCall = function(responseCallback, jsonReviver) {
+
+ // Asynchronous http requests may still count towards the "loading" time of a page
+ // To prevent a dead lock with the loading page waiting for a blocking event to finish (example: polling),
+ // defer any async requests.
+ var requestUri = composeUri();
+ var request = createXhrRequest(requestUri, true);
+ composePostData();
+
+ request.onreadystatechange = function() {
+ // continue if the process is completed
+ if (request.readyState == 4 && request.status == 200) {
+ // retrieve the response
+ var response = JSON.parse(request.responseText, jsonReviver);
+ responseCallback(response); //call the client code with the parsed response
+ }
+ };
+
+ if(_frameworkReady) {
+ try {
+ request.send(postData);
+ } catch(e) {}
+ } else {
+ _deferredRequests.push( { 'request': request, 'postData': postData } );
+ }
+ };
+ }
+ };
+
+ this.blackberry.transport.call = function(url, opts, callback) {
+ var request = new blackberry.transport.RemoteFunctionCall(url), name;
+
+ opts = opts || {};
+
+ if (opts.get) {
+ for (name in opts.get) {
+ if (Object.hasOwnProperty.call(opts.get, name)) {
+ request.addParam(name, opts.get[name]);
+ }
+ }
+ }
+
+ if (opts.post) {
+ for (name in opts.post) {
+ if (Object.hasOwnProperty.call(opts.post, name)) {
+ request.addPostParam(name, opts.post[name]);
+ }
+ }
+ }
+
+ return opts.async ? request.makeAsyncCall(callback) : request.makeSyncCall(callback);
+ };
+
+ this.blackberry.transport.poll = function(url, opts, callback) {
+ opts = opts || {};
+ opts.async = true;
+
+ blackberry.transport.call(url, opts, function (response) {
+ if (callback(response)) {
+ this.blackberry.transport.poll(url, opts, callback);
+ }
+ });
+ };
+})();
56 api/CommonAPI/sharedglobal/4_events_ns.js
@@ -0,0 +1,56 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+(function () {
+ if(!this.blackberry) {
+ return;
+ }
+
+ var bb = this.blackberry;
+
+
+ function EventMap(){
+ var handlers = [];
+
+ this.getHandlerById = function(handlerId){
+ return handlers[handlerId];
+ };
+
+ this.addHandler = function(handler){
+ handlers.push(handler);
+ return handlers.length - 1;
+ };
+
+ this.removeHandler = function(handlerId){
+ if(handlerId > -1 && handlerId < handlers.length) {
+ delete handlers[handlerId]; //cannot splice because all published IDs would refer to the wrong handler
+ }
+ };
+
+ };
+
+ bb.events = {
+ eventsMap : new EventMap(),
+
+ registerEventHandler : function (eventName, eventCallback, eventParams) {
+ var handlerId = blackberry.events.eventsMap.addHandler(eventCallback);
+ return handlerId;
+ },
+
+ getEventHandler : function(handlerId) {
+ return blackberry.events.eventsMap.getHandlerById(handlerId);
+ }
+ };
+})();
38 api/CommonAPI/sharedglobal/5_blob.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * 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.
+ */
+(function () {
+ var BLOB_API_URL = "service/blob";
+
+ function createBlob(id, length) {
+ function Blob(id, length) {
+ this.length = length;
+ }
+
+ Blob.prototype.slice = function(offset, length) {
+ var request = new blackberry.transport.RemoteFunctionCall(BLOB_API_URL + "/sliceBlob");
+
+ request.addParam("id", id);
+ request.addParam("offset", offset);
+ request.addParam("length", length);
+
+ var newBlobData = request.makeSyncCall();
+
+ return createBlob(newBlobData.id, newBlobData.length);
+ };
+
+ return new Blob(id, length);
+ }
+}());
482 api/CommonAPI/sharedglobal/json2.js
@@ -0,0 +1,482 @@
+/*
+ http://www.JSON.org/json2.js
+ 2011-02-23
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ See http://www.JSON.org/js.html
+
+
+ This code should be minified before deployment.
+ See http://javascript.crockford.com/jsmin.html
+
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+ NOT CONTROL.
+
+
+ This file creates a global JSON object containing two methods: stringify
+ and parse.
+
+ JSON.stringify(value, replacer, space)
+ value any JavaScript value, usually an object or array.
+
+ replacer an optional parameter that determines how object
+ values are stringified for objects. It can be a
+ function or an array of strings.
+
+ space an optional parameter that specifies the indentation
+ of nested structures. If it is omitted, the text will
+ be packed without extra whitespace. If it is a number,
+ it will specify the number of spaces to indent at each
+ level. If it is a string (such as '\t' or '&nbsp;'),
+ it contains the characters used to indent at each level.
+
+ This method produces a JSON text from a JavaScript value.
+
+ When an object value is found, if the object contains a toJSON
+ method, its toJSON method will be called and the result will be
+ stringified. A toJSON method does not serialize: it returns the
+ value represented by the name/value pair that should be serialized,
+ or undefined if nothing should be serialized. The toJSON method
+ will be passed the key associated with the value, and this will be
+ bound to the value
+
+ For example, this would serialize Dates as ISO strings.
+
+ Date.prototype.toJSON = function (key) {
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ You can provide an optional replacer method. It will be passed the
+ key and value of each member, with this bound to the containing
+ object. The value that is returned from your method will be
+ serialized. If your method returns undefined, then the member will
+ be excluded from the serialization.
+
+ If the replacer parameter is an array of strings, then it will be
+ used to select the members to be serialized. It filters the results
+ such that only members with keys listed in the replacer array are
+ stringified.
+
+ Values that do not have JSON representations, such as undefined or
+ functions, will not be serialized. Such values in objects will be
+ dropped; in arrays they will be replaced with null. You can use
+ a replacer function to replace those with JSON values.
+ JSON.stringify(undefined) returns undefined.
+
+ The optional space parameter produces a stringification of the
+ value that is filled with line breaks and indentation to make it
+ easier to read.
+
+ If the space parameter is a non-empty string, then that string will
+ be used for indentation. If the space parameter is a number, then
+ the indentation will be that many spaces.
+
+ Example:
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
+ // text is '["e",{"pluribus":"unum"}]'
+
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+ text = JSON.stringify([new Date()], function (key, value) {
+ return this[key] instanceof Date ?
+ 'Date(' + this[key] + ')' : value;
+ });
+ // text is '["Date(---current time---)"]'
+
+
+ JSON.parse(text, reviver)
+ This method parses a JSON text to produce an object or array.
+ It can throw a SyntaxError exception.
+
+ The optional reviver parameter is a function that can filter and
+ transform the results. It receives each of the keys and values,
+ and its return value is used instead of the original value.
+ If it returns what it received, then the structure is not modified.
+ If it returns undefined then the member is deleted.
+
+ Example:
+
+ // Parse the text. Values that look like ISO date strings will
+ // be converted to Date objects.
+
+ myData = JSON.parse(text, function (key, value) {
+ var a;
+ if (typeof value === 'string') {
+ a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+ if (a) {
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+ +a[5], +a[6]));
+ }
+ }
+ return value;
+ });
+
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+ var d;
+ if (typeof value === 'string' &&
+ value.slice(0, 5) === 'Date(' &&
+ value.slice(-1) === ')') {
+ d = new Date(value.slice(5, -1));
+ if (d) {
+ return d;
+ }
+ }
+ return value;
+ });
+
+
+ This is a reference implementation. You are free to copy, modify, or
+ redistribute.
+*/
+
+/*jslint evil: true, strict: false, regexp: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
+ test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+var JSON;
+if (!JSON) {
+ JSON = {};
+}
+
+(function () {
+ "use strict";
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ //if (typeof Date.prototype.toJSON !== 'function') {
+
+ Date.prototype.toJSON = function (key) {
+
+ /*return isFinite(this.valueOf()) ?
+ this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z' : null;
+ */
+ return this.valueOf();
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ //}
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+ escapable.lastIndex = 0;
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+// Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+// What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+ return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+ case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+// Is the value an array?
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+ v = partial.length === 0 ? '[]' : gap ?
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ if (typeof rep[i] === 'string') {
+ k = rep[i];
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' : gap ?
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
+ '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+ if (typeof JSON.stringify !== 'function') {
+ JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+ return str('', {'': value});
+ };
+ }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+ text = String(text);
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+ if (/^[\],:{}\s]*$/
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+ j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+}());
336 api/CommonAPI/src/blackberry/common/push/PushDaemon.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * 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.
+ */
+package blackberry.common.push;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import javax.microedition.io.StreamConnection;
+
+import net.rim.blackberry.api.push.PushApplication;
+import net.rim.blackberry.api.push.PushApplicationStatus;
+import net.rim.device.api.io.http.PushInputStream;
+import net.rim.device.api.system.Application;
+import net.rim.device.api.system.ApplicationDescriptor;
+import net.rim.device.api.system.ApplicationManager;
+import net.rim.device.api.system.ApplicationManagerException;
+import net.rim.device.api.system.CodeSigningKey;
+import net.rim.device.api.system.ControlledAccess;
+import net.rim.device.api.system.EventLogger;
+import net.rim.device.api.system.RuntimeStore;
+import net.rim.device.api.util.DataBuffer;
+import blackberry.common.util.ID;
+import blackberry.core.ApplicationRegistry;
+import blackberry.core.WidgetProperties;
+
+/**
+ * The push daemon is responsible for receiving push messages, store them in a message queue and notify the UI application. It
+ * launches the UI application if it is not running.
+ *
+ *
+ */
+public class PushDaemon extends Application implements PushApplication {
+
+ // Registration status
+ public static final int SUCCESS = 0;
+ public static final int NETWORK_ERROR = 1;
+ public static final int REJECTED_BY_SERVER = 2;
+ public static final int INVALID_PARAMETERS = 3;
+ public static final int GENERAL_ERROR = -1;
+ private static final int CHUNK_SIZE = 256;
+
+ private int _maxQueueCap;
+ private String _entryPage;
+ private DaemonStore _daemonStore;
+ private CommandListener _commandListener;
+ private ApplicationDescriptor _uiAppDesc;
+
+ /**
+ * Data object used between the daemon and widget to communicate
+ */
+ final public static class DaemonStore {
+ private static final long DAEMON_STORE_ID;
+
+ private Vector _commandQueue;
+ private Vector _messageQueue;
+
+ static {
+ DAEMON_STORE_ID = ID.getUniqueID( "DAEMON_STORE_ID" );
+ }
+
+ public static DaemonStore loadFromStore() {
+ DaemonStore store = null;
+
+ Object storeObject = RuntimeStore.getRuntimeStore().get( DAEMON_STORE_ID );
+ if( storeObject != null ) {
+ store = (DaemonStore) storeObject;
+ } else {
+ store = new DaemonStore();
+ CodeSigningKey codeSigningKey = CodeSigningKey.get( store );
+ RuntimeStore.getRuntimeStore().put( DAEMON_STORE_ID, new ControlledAccess( store, codeSigningKey ) );
+ }
+
+ return store;
+ }
+
+ private DaemonStore() {
+ _commandQueue = new Vector();
+ _messageQueue = new Vector();
+ }
+
+ /**
+ * Get vector holding command messages to the daemon
+ *
+ * @return command queue vector
+ */
+ public Vector getCommandQueue() {
+ return _commandQueue;
+ }
+
+ /**
+ * Get vector holding push messages
+ *
+ * @return message queue object
+ */
+ public Vector getMessageQueue() {
+ return _messageQueue;
+ }
+
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param entryPage
+ * The page of the UI application to be shown if it is not running
+ * @param maxQueueCap
+ * The maximum number of message to store in the message queue
+ */
+ public PushDaemon( String entryPage, int maxQueueCap ) {
+ _entryPage = entryPage;
+ _maxQueueCap = maxQueueCap;
+
+ _daemonStore = DaemonStore.loadFromStore();
+ _daemonStore.getCommandQueue().removeAllElements(); // clear all commands
+
+ _commandListener = new CommandListener();
+ _commandListener.start();
+
+ _uiAppDesc = new ApplicationDescriptor( ApplicationDescriptor.currentApplicationDescriptor(), PushPersistentStore.getAppDescArgs() );
+
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), "PushDaemon is started.".getBytes() );
+ }
+
+ /**
+ * onMessage handle inbound push notifications
+ *
+ * @param stream
+ * inbound PushInputStream
+ *
+ * @param conn
+ * inbound StreamConnection
+ *
+ * @see PushApplication#.onMessage(PushInputStream, StreamConnection)
+ */
+ public void onMessage( PushInputStream inputStream, StreamConnection conn ) {
+ handleMessage( inputStream, conn );
+ }
+
+ /**
+ * onStatusChange Called when Push Status changes
+ *
+ * @param status
+ * changed push state.
+ *
+ * @see PushApplication#onStatusChange(PushApplicationStatus)
+ */
+ public void onStatusChange( PushApplicationStatus status ) {
+ handleStatusChange( status );
+ }
+
+ private void launchUI() {
+ // launch UI if it is not running
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), ( "Check if application is running" ).getBytes(),
+ EventLogger.DEBUG_INFO );
+ if( !ApplicationRegistry.isAppRunning() ) {
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), ( "Launch application" ).getBytes(),
+ EventLogger.DEBUG_INFO );
+ ApplicationDescriptor newAppDesc = new ApplicationDescriptor( _uiAppDesc, new String[] { _entryPage } );
+ try {
+ ApplicationManager.getApplicationManager().runApplication( newAppDesc, false );
+ } catch( ApplicationManagerException e ) {
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), ( "Error launching UI" ).getBytes(),
+ EventLogger.ERROR );
+ }
+ }
+ }
+
+ private void handleMessage( PushInputStream inputStream, StreamConnection conn ) {
+
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), ( "handleMessage is called." ).getBytes(), EventLogger.DEBUG_INFO );
+
+ DataBuffer db = null;
+ try {
+ /**
+ * Does this need to be synch'd? This should be a single threaded instance that runs autonomously on a port.
+ *
+ * Might want to call this in the the PushService class to catch IOPortAlreadyBoundException so we can properly throw
+ * this back up via JavaScript so the developer realizes that the port they tried to open is unavailable.
+ */
+
+ Vector messageQueue = _daemonStore.getMessageQueue();
+
+ // extract the data from the input stream
+ db = new DataBuffer();
+ byte[] data = new byte[ CHUNK_SIZE ];
+ int chunk = 0;
+ while( -1 != ( chunk = inputStream.read( data ) ) ) {
+ db.write( data, 0, chunk );
+ }
+
+ // trim the array - the buffer in DataBuffer grows
+ // past the size and fills with empty chars
+ db.trim();
+
+ // synchronize this block to avoid race conditions with the queue
+ synchronized( messageQueue ) {
+ // Create push object, add to queue for callback thread
+ PushData pd = new PushData( conn, inputStream, db.getArray() );
+ if( _maxQueueCap > 0 ) {
+ if( messageQueue.size() >= _maxQueueCap ) {
+ messageQueue.removeElementAt( 0 );
+ }
+ }
+
+ messageQueue.addElement( pd );
+ messageQueue.notify();
+ }
+ } catch( IOException e1 ) {
+ // a problem occurred with the input stream
+ // however, the original StreamConnectionNotifier is still valid
+ if( inputStream != null ) {
+ try {
+ inputStream.close();
+ } catch( IOException e2 ) {
+ }
+ }
+ if( conn != null ) {
+ try {
+ conn.close();
+ } catch( IOException e2 ) {
+ }
+ }
+ }
+
+ launchUI();
+ }
+
+ private void handleStatusChange( PushApplicationStatus applicationStatus ) {
+ int result = GENERAL_ERROR;
+ boolean simChange = false;
+ int status = applicationStatus.getStatus();
+
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), ( "handleStatusChange is called, status:" + status ).getBytes(), EventLogger.DEBUG_INFO );
+
+ if( status == PushApplicationStatus.STATUS_ACTIVE ) {
+ result = SUCCESS;
+ } else if( status == PushApplicationStatus.STATUS_FAILED ) {
+ if( applicationStatus.getReason() == PushApplicationStatus.REASON_NETWORK_ERROR ) {
+ result = NETWORK_ERROR;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_REJECTED_BY_SERVER ) {
+ result = REJECTED_BY_SERVER;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_INVALID_PARAMETERS ) {
+ result = INVALID_PARAMETERS;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_SIM_CHANGE ) {
+ simChange = true;
+ }
+ } else if( status == PushApplicationStatus.STATUS_NOT_REGISTERED ) {
+ if( applicationStatus.getReason() == PushApplicationStatus.REASON_NETWORK_ERROR ) {
+ result = NETWORK_ERROR;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_REJECTED_BY_SERVER ) {
+ result = REJECTED_BY_SERVER;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_INVALID_PARAMETERS ) {
+ result = INVALID_PARAMETERS;
+ } else if( applicationStatus.getReason() == PushApplicationStatus.REASON_SIM_CHANGE ) {
+ simChange = true;
+ }
+ }
+
+ Vector messageQueue = _daemonStore.getMessageQueue();
+
+ synchronized( messageQueue ) {
+ Object data;
+ if( simChange ) {
+ data = new SimChangeData();
+ } else {
+ data = new StatusChangeData( result );
+ }
+ messageQueue.addElement( data );
+ messageQueue.notify();
+ }
+
+ launchUI();
+ }
+
+ public static class StatusChangeData {
+ private int _status;
+
+ public StatusChangeData( int status ) {
+ _status = status;
+ }
+
+ public int getStatus() {
+ return _status;
+ }
+ }
+
+ public static class SimChangeData {
+ }
+
+ public class CommandListener extends Thread {
+
+ private boolean _stop;
+
+ public CommandListener() {
+ _stop = false;
+ }
+
+ /**
+ * @see java.lang.Thread
+ */
+ public void run() {
+ while( !_stop ) {
+
+ Vector commandQueue = _daemonStore.getCommandQueue();
+
+ synchronized( commandQueue ) {
+ if( commandQueue.size() == 0 ) {
+ try {
+ commandQueue.wait();
+ } catch( Exception e ) {
+ // ignore - check loop
+ }
+ }
+ if( commandQueue.size() > 0 ) {
+ _stop = true;
+ }
+ }
+ }
+ EventLogger.logEvent( WidgetProperties.getInstance().getGuid(), "PushDaemon exits".getBytes() );
+ System.exit( 0 );
+ }
+ }
+ }
168 api/CommonAPI/src/blackberry/common/push/PushData.java
@@ -0,0 +1,168 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+package blackberry.common.push;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import javax.microedition.io.StreamConnection;
+
+import net.rim.device.api.io.http.HttpServerConnection;
+import net.rim.device.api.io.http.MDSPushInputStream;
+import net.rim.device.api.io.http.PushInputStream;
+
+/**
+ * Encapsulates an individual push message received from an open push channel.
+ */
+public final class PushData {
+
+ private boolean _isChannelEncrypted;
+ private byte[] _payload;
+ private HttpServerConnection _httpConnection;
+ private String _source;
+ private InputStream _input;
+ private PushInputStream _pushStream;
+ private boolean _ack;
+
+ /**
+ * Constructor
+ *
+ * @param conn
+ * StreamConnection that this message was received on.
+ * @param input
+ * InputSteram this message was received on.
+ * @param payload
+ * The byte array payload of this message.
+ */
+ public PushData( StreamConnection conn, InputStream input, byte[] payload ) {
+ _httpConnection = (HttpServerConnection) conn;
+ _input = input;
+ _payload = payload;
+ _pushStream = createPushInputStream( conn, input );
+ _isChannelEncrypted = _pushStream.isChannelEncrypted();
+ _source = _pushStream.getSource();
+ }
+
+ /**
+ * Sends a response to the sender of the push message indicating the message has been accepted.
+ */
+ public void accept() throws IOException {
+ if( !_ack ) {
+ _pushStream.accept();
+ _ack = true;
+ }
+ }
+
+ /**
+ * Sends a response to the sender of the push message indicating the message has been declined with the given reason.
+ *
+ * @param reason
+ * The reason the message was declined - see net.rim.device.api.io.http.PushInputStream
+ */
+ public void decline( int reason ) throws IOException {
+ if( !_ack ) {
+ _pushStream.decline( reason );
+ _ack = true;
+ }
+ }
+
+ /**
+ * Gets a header field key by index.
+ *
+ * @param index
+ * the index of the header field.
+ * @return the key of the nth header field or null if the array index is out of range.
+ */
+ public String getHeaderField( int index ) throws IOException {
+ return _httpConnection.getHeaderField( index );
+ }
+
+ /**
+ * Returns the value of the named header field.
+ *
+ * @param field
+ * of a header field.
+ * @return the value of the named header field, or null if there is no such field in the header.
+ */
+ public String getHeaderField( String field ) throws IOException {
+ return _httpConnection.getHeaderField( field );
+ }
+
+ /**
+ * Returns the requested URI.
+ *
+ * @return Return the requested URI.
+ */
+ public String getRequestURI() throws IOException {
+ return _httpConnection.getRequestURI();
+ }
+
+ /**
+ * Retrieves the source for this push stream.
+ *
+ * @return String form of the source of this push; it could be a UID for a connection, IPv4 address, or SMSC.
+ */
+ public String getSource() {
+ return _source;
+ }
+
+ /**
+ * Determines if the channel is encrypted.
+ *
+ * @return True if this channel is encrypted; otherwise, false.
+ */
+ public boolean isChannelEncrypted() {
+ return _isChannelEncrypted;
+ }
+
+ /**
+ * Returns the payload of this message as a byte-array.
+ *
+ * @return the payload of this push message.
+ */
+ public byte[] getPayload() {
+ return _payload;
+ }
+
+ /**
+ * Cleans up this message - calling this method will cause other methods for this object to throw exceptions if called
+ * afterwards.
+ */
+ public void discard() {
+ try {
+ _input.close();
+ } catch( IOException ioe ) {
+ }
+ try {
+ _httpConnection.close();
+ } catch( IOException ioe ) {
+ }
+ }
+
+ /**
+ * Creates a PushInputStream based on the transport type.
+ *
+ * @param stream
+ * the StreamConnection for the message.
+ * @param input
+ * the InputStream for this message.
+ * @return an implementation of PushInputStream.
+ */
+ private PushInputStream createPushInputStream( StreamConnection stream, InputStream input ) {
+ PushInputStream result = new MDSPushInputStream( (HttpServerConnection) stream, input );
+ return result;
+ }
+}
134 api/CommonAPI/src/blackberry/common/push/PushPersistentStore.java
@@ -0,0 +1,134 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+package blackberry.common.push;
+
+import java.util.Hashtable;
+
+import net.rim.device.api.system.CodeSigningKey;
+import net.rim.device.api.system.ControlledAccess;
+import net.rim.device.api.system.PersistentObject;
+import net.rim.device.api.system.PersistentStore;
+import blackberry.common.settings.SettingsManager;
+import blackberry.common.util.ID;
+
+/**
+ * Class to persistent push related stuff (i.e. type, port, application descriptor arguments)
+ */
+public class PushPersistentStore {
+
+ private static final long LASTKNOWN_ID;
+
+ static {
+ LASTKNOWN_ID = ID.getUniqueID( "LASTKNOWN_ID" );
+ }
+
+ /**
+ * Get the last known push service type
+ *
+ * @return push service type
+ */
+ public static int getLastKnownType() {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info != null && info.containsKey( "type" ) ) {
+ return ( (Integer) info.get( "type" ) ).intValue();
+ }
+
+ return -1;
+ }
+
+ /**
+ * Set the last known push service type
+ *
+ * @param type
+ * push service type
+ */
+ public static void setLastKnownType( int type ) {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info == null ) {
+ info = SettingsManager.createStorableObject();
+ CodeSigningKey codeSigningKey = CodeSigningKey.get( info );
+ persistentObject.setContents( new ControlledAccess( info, codeSigningKey ) );
+ }
+ info.put( "type", new Integer( type ) );
+ persistentObject.commit();
+ }
+
+ /**
+ * Get the last known push service port
+ *
+ * @return push service port
+ */
+ public static int getLastKnownPort() {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info != null && info.containsKey( "port" ) ) {
+ return ( (Integer) info.get( "port" ) ).intValue();
+ }
+
+ return -1;
+ }
+
+ /**
+ * Set the last known push service port
+ *
+ * @param port
+ * push service port
+ */
+ public static void setLastKnownPort( int port ) {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info == null ) {
+ info = SettingsManager.createStorableObject();
+ CodeSigningKey codeSigningKey = CodeSigningKey.get( info );
+ persistentObject.setContents( new ControlledAccess( info, codeSigningKey ) );
+ }
+ info.put( "port", new Integer( port ) );
+ persistentObject.commit();
+ }
+
+ /**
+ * Get the application descriptor arguments
+ *
+ * @return <code>ApplicationDescriptor</code>
+ */
+ public static String[] getAppDescArgs() {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info != null && info.containsKey( "appDescriptor" ) ) {
+ return (String[]) info.get( "appDescriptor" );
+ }
+ return null;
+ }
+
+ /**
+ * Set the application descriptor arguments
+ *
+ * @param application
+ * descriptor arguments
+ */
+ public static void setAppDescArgs( String[] args ) {
+ PersistentObject persistentObject = PersistentStore.getPersistentObject( LASTKNOWN_ID );
+ Hashtable info = (Hashtable) persistentObject.getContents();
+ if( info == null ) {
+ info = SettingsManager.createStorableObject();
+ persistentObject.setContents( info );
+ }
+ info.put( "appDescriptor", args );
+ persistentObject.commit();
+ }
+}
50 api/CommonAPI/src/blackberry/common/settings/SettingsManager.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * 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.
+ */
+
+package blackberry.common.settings;
+
+import java.util.Hashtable;
+
+
+/**
+ * Used to create persistent-storable settings objects
+ */
+public class SettingsManager {
+ private static SettingsStoreFactory _factory = null;
+
+ private SettingsManager() {
+
+ }
+
+ /**
+ * Set the object factory for this settings manager
+ * @param factory the factory class used to create storable objects
+ */
+ public static void setFactory(SettingsStoreFactory factory) {
+ _factory = factory;
+ }
+
+ /**
+ * create a persistent-storable object
+ * @return a Hashtable that can be used to store objects
+ */
+ public static Hashtable createStorableObject() {
+ if(_factory == null ) {
+ throw new IllegalStateException( SettingsManager.class.getName() + " is not initialized" );
+ }
+ return _factory.createStorableObject();
+ }
+}
31 api/CommonAPI/src/blackberry/common/settings/SettingsStoreFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * 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.
+ */
+
+package blackberry.common.settings;
+
+import java.util.Hashtable;
+
+/**
+ * Interface to allow factory to jump across the auto-generated namespace
+ * and the apis namespaces
+ */
+public interface SettingsStoreFactory {
+ /**
+ * create an object that can be used to store settings
+ * @return a Hashtable that can be used to store settings
+ */
+ public Hashtable createStorableObject();
+}
67 api/CommonAPI/src/blackberry/common/util/FeaturesHash.java
@@ -0,0 +1,67 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+package blackberry.common.util;
+
+import java.util.Hashtable;
+
+/**
+ * @author yiwu
+ *
+ */
+public class FeaturesHash {
+
+ private static Hashtable _featuresHashed = new Hashtable();
+
+ /**
+ * Returns the object for the given feature.
+ *
+ * @param feature
+ * The feature
+ * @return The object
+ */
+ public static Object getObjectForLoadedFeature( final String feature ) {
+ return _featuresHashed.get( feature );
+ }
+
+ /**
+ * Sets object for the given feature.
+ *
+ * @param feature
+ * The feature
+ * @param obj
+ * The object
+ * @return Previous object associated with the feature or <code>null</code> if no object associated with the given feature.
+ */
+ public static Object setObjectForLoadedFeature( final String feature, final Object obj ) {
+ return _featuresHashed.put( feature, obj );
+ }
+
+ /**
+ * Returns a formatted feature name.
+ *
+ * @param namespace
+ * The namespace
+ * @param name
+ * The feature name
+ * <p>
+ * In 6.0 the feature name which is a superset of other feature (i.e. blackberry.audio.Player is superset of
+ * blackberry.audio) isn't handled in the same manner as in 5.0 (instead it's looking in the blackberry.audio
+ * namespace after the Player name).
+ */
+ public static String formatFeature( final String namespace, final String name ) {
+ return namespace + "." + name;
+ }
+}
56 api/CommonAPI/src/blackberry/common/util/ID.java
@@ -0,0 +1,56 @@
+/*
+* Copyright 2010-2011 Research In Motion Limited.
+*
+* 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.
+*/
+
+package blackberry.common.util;
+
+import java.lang.IllegalStateException;
+
+/**
+ *
+ */
+public final class ID {
+
+ private static long _packageNameHash = 0;
+
+
+ private ID() {
+
+ }
+
+ // Init ID generator
+ public static void init(Object seed) {
+ // package name is auto-generated to be unique
+ if(seed instanceof String) {
+ _packageNameHash = seed.hashCode();
+ } else {
+ _packageNameHash = seed.getClass().getName().hashCode();