PageRenderTime 30ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/SeekDeepWithin/src/com/seekdeepwithin/DataAccess/SdwApi.java

#
Java | 358 lines | 255 code | 22 blank | 81 comment | 45 complexity | fe2cacfc9e8010f02251b1018cd59a88 MD5 | raw file
Possible License(s): AGPL-1.0, Apache-2.0
  1. /*
  2. * Copyright (C) 2013 SeekDeepWithin.com
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. package com.seekdeepwithin.DataAccess;
  19. import com.seekdeepwithin.Data.*;
  20. import com.seekdeepwithin.MainController;
  21. import com.sun.jersey.api.client.*;
  22. import com.sun.jersey.api.client.config.ClientConfig;
  23. import com.sun.jersey.api.client.config.DefaultClientConfig;
  24. import java.util.*;
  25. import javafx.scene.control.*;
  26. import javax.ws.rs.core.*;
  27. import org.json.*;
  28. /**
  29. * User: Jonathan Montiverdi
  30. * Date: Sep 19, 2013
  31. *
  32. * This class will connect to seek deep within.com and access the REST API.
  33. */
  34. public class SdwApi
  35. {
  36. private static SdwApi s_Instance;
  37. private Client m_Client;
  38. private WebResource m_Service;
  39. private String m_ApiVersion;
  40. private String m_DbVersion;
  41. /**
  42. * Private constructor to prevent improper use.
  43. */
  44. private SdwApi ()
  45. {
  46. ClientConfig config = new DefaultClientConfig ();
  47. this.m_Client = Client.create (config);
  48. this.m_Service = this.m_Client.resource (UriBuilder.fromUri ("http://seekdeepwithin.com/code/api.php").build ());
  49. }
  50. /**
  51. * Gets the seek deep with API instance.
  52. * @return The one and only instance of the seek deep within API.
  53. */
  54. public static SdwApi getInstance ()
  55. {
  56. if (s_Instance == null) {
  57. s_Instance = new SdwApi ();
  58. }
  59. return s_Instance;
  60. }
  61. /**
  62. * Gets the version of the API on the seek deep within server.
  63. * @return The server's API version.
  64. */
  65. public String getApiVersion ()
  66. {
  67. if (this.m_ApiVersion == null || this.m_ApiVersion.isEmpty ()) {
  68. this.m_ApiVersion = this.m_Service.queryParam ("action", "getapiversion")
  69. .accept (MediaType.TEXT_PLAIN).get (String.class);
  70. }
  71. return this.m_ApiVersion;
  72. }
  73. /**
  74. * Gets the version of the database on the seek deep within server.
  75. * @return The server's database version.
  76. */
  77. public String getDatabaseVersion ()
  78. {
  79. if (this.m_DbVersion == null || this.m_DbVersion.isEmpty ()) {
  80. this.m_DbVersion = this.m_Service.queryParam ("action", "getdbversion")
  81. .accept (MediaType.TEXT_PLAIN).get (String.class);
  82. }
  83. return this.m_DbVersion;
  84. }
  85. /**
  86. * Gets the list of all the areas.
  87. * @return Areas list - Map of 'AreaID' and 'AreaName';
  88. */
  89. public Map<Integer, String> getAllAreas ()
  90. {
  91. Map<Integer, String> data = new HashMap<> ();
  92. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getallareas")
  93. .accept (MediaType.APPLICATION_JSON)
  94. .get (String.class));
  95. Iterator areaList = json.keys ();
  96. while (areaList.hasNext ()) {
  97. String areaId = areaList.next ().toString ();
  98. data.put (Integer.parseInt (areaId), json.getString (areaId));
  99. }
  100. return data;
  101. }
  102. /**
  103. * Gets the list of all the style types.
  104. * @return Style type list - Map of 'StyleTypeId' and 'StyleTypeName';
  105. */
  106. public Map<Integer, String> getAllStyleTypes ()
  107. {
  108. Map<Integer, String> data = new HashMap<> ();
  109. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getallstyletypes")
  110. .accept (MediaType.APPLICATION_JSON)
  111. .get (String.class));
  112. Iterator styleTypeList = json.keys ();
  113. while (styleTypeList.hasNext ()) {
  114. String styleTypeId = styleTypeList.next ().toString ();
  115. data.put (Integer.parseInt (styleTypeId), json.getString (styleTypeId));
  116. }
  117. return data;
  118. }
  119. /**
  120. * Gets the list of all the styles on the server.
  121. * @return List of styles.
  122. */
  123. public List<Style> getAllStyles ()
  124. {
  125. List<Style> styles = new ArrayList<> ();
  126. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getallstyles")
  127. .accept (MediaType.APPLICATION_JSON)
  128. .get (String.class));
  129. Iterator styleList = json.keys ();
  130. while (styleList.hasNext ()) {
  131. String styleId = styleList.next ().toString ();
  132. JSONObject styleItem = json.getJSONObject (styleId);
  133. styles.add (new Style (Integer.parseInt (styleId), styleItem.getInt ("typeid"), styleItem.getString ("style")));
  134. }
  135. return styles;
  136. }
  137. /**
  138. * Gets the list of bookList on the seek deep within server.
  139. */
  140. public ArrayList<Book> getBookList ()
  141. {
  142. ArrayList<Book> books = new ArrayList<> ();
  143. try {
  144. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "listbooks")
  145. .accept (MediaType.APPLICATION_JSON)
  146. .get (String.class));
  147. Iterator bookList = json.keys ();
  148. while (bookList.hasNext ()) {
  149. String bookItem = bookList.next ().toString ();
  150. JSONObject bookData = json.getJSONObject (bookItem);
  151. books.add (this.buildBook (bookItem, bookData));
  152. }
  153. } catch (UniformInterfaceException exception) {
  154. Dialogs.showErrorDialog (MainController.getInstance ().getStage (),
  155. "Unable to download library book information from the server! Please try again later.",
  156. "An error occured while downloading the library from the server.", "Error", exception);
  157. }
  158. return books;
  159. }
  160. /**
  161. * Gets the book data for the book with the given ID.
  162. * @param title Title of book to get sub books for.
  163. * @return A book object with the data downloaded from the server.
  164. */
  165. public Book getBookData (String title)
  166. {
  167. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getbookdata")
  168. .queryParam ("book", title)
  169. .accept (MediaType.APPLICATION_JSON)
  170. .get (String.class));
  171. return buildBook (title, json);
  172. }
  173. /**
  174. * Builds a book object from the given information.
  175. * @param title Title of book.
  176. * @param json Book's data in JSON format.
  177. * @return A book object.
  178. * @throws NumberFormatException
  179. * @throws JSONException
  180. */
  181. private Book buildBook (String title, JSONObject json) throws NumberFormatException, JSONException
  182. {
  183. Book book = new Book (title, json.getInt ("id"));
  184. book.setAuthor (json.getString ("author"));
  185. book.setInfo (json.getString ("info"));
  186. book.setDate (json.getString ("date"));
  187. book.setSubTitle (json.optString ("subtitle"));
  188. book.setAbbreviation (json.getString ("abbreviation"));
  189. book.setHasSubBooks (json.getInt ("hassubbooks") == 1);
  190. book.setHasChapters (json.getInt ("haschapters") == 1);
  191. book.setAmazonId (json.getString ("amazonid"));
  192. book.setIsSubBook (json.getInt ("issubbook") == 1);
  193. // Sources
  194. JSONArray sources = json.optJSONArray ("sources");
  195. if (sources != null) {
  196. int length = sources.length ();
  197. for (int i = 0; i < length; i++) {
  198. JSONObject sourceData = sources.getJSONObject (i);
  199. book.addSource (sourceData.getInt ("sourceid"), sourceData.getString ("source"),
  200. sourceData.getInt ("nameid"), sourceData.getString ("name"));
  201. }
  202. }
  203. // Translators
  204. JSONObject translators = json.optJSONObject ("translators");
  205. if (translators != null) {
  206. Iterator translatorList = translators.keys ();
  207. while (translatorList.hasNext ()) {
  208. String translatorId = translatorList.next ().toString ();
  209. String translator = translators.getString (translatorId);
  210. book.addTranslator (Integer.parseInt (translatorId), translator);
  211. }
  212. }
  213. return book;
  214. }
  215. /**
  216. * Gets a list of sub books for the given book.
  217. * @param parentBook Book to get sub books for.
  218. */
  219. public void getSubBooks (Book parentBook)
  220. {
  221. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getsubbooklist")
  222. .queryParam ("bookid", String.valueOf (parentBook.getId ()))
  223. .accept (MediaType.APPLICATION_JSON)
  224. .get (String.class));
  225. Iterator subBookList = json.keys ();
  226. while (subBookList.hasNext ()) {
  227. String subBookListId = subBookList.next ().toString ();
  228. JSONObject subBookItem = json.getJSONObject (subBookListId);
  229. String subBookTitle = subBookItem.getString ("title");
  230. //int subBookId = subBookItem.getInt ("subbookid");
  231. int subBookOrder = subBookItem.getInt ("order");
  232. int subBookLinkedId = subBookItem.optInt ("linkedbooklistid", -1);
  233. Book b = this.getBookData (subBookTitle);
  234. SubBook subBook = new SubBook (b, Integer.parseInt (subBookListId), parentBook);
  235. subBook.setOrder (subBookOrder);
  236. if (subBookLinkedId != -1) {
  237. subBook.setLinkedId (subBookLinkedId);
  238. }
  239. parentBook.getSubBooks ().add (subBook);
  240. }
  241. }
  242. /**
  243. * Gets the list of chapters for the given sub book.
  244. * @param subBook Sub book to get chapters for.
  245. */
  246. public void getChapters (SubBook subBook)
  247. {
  248. int linkId = subBook.getLinkedId ();
  249. Integer subBookId = linkId == -1 ? subBook.getSubBookListId () : linkId;
  250. JSONObject json = new JSONObject (this.m_Service.queryParam ("action", "getchapterlist")
  251. .queryParam ("subbookid", subBookId.toString ())
  252. .accept (MediaType.APPLICATION_JSON)
  253. .get (String.class));
  254. Iterator chapterList = json.keys ();
  255. while (chapterList.hasNext ()) {
  256. String chapterListId = chapterList.next ().toString ();
  257. JSONObject chapterItem = json.getJSONObject (chapterListId);
  258. String chapterName = chapterItem.getString ("name");
  259. int chapterId = chapterItem.getInt ("chapterid");
  260. int chapterOrder = chapterItem.getInt ("order");
  261. JSONObject footer = chapterItem.optJSONObject ("footer");
  262. JSONObject header = chapterItem.optJSONObject ("header");
  263. Chapter chapter = new Chapter (chapterId, chapterName, Integer.parseInt (chapterListId));
  264. chapter.setOrder (chapterOrder);
  265. if (footer != null) {
  266. chapter.setFooter (footer.getInt ("id"), footer.getString ("footer"));
  267. }
  268. if (header != null) {
  269. chapter.setHeader (header.getInt ("id"), header.getString ("header"));
  270. }
  271. subBook.getChapters ().add (chapter);
  272. }
  273. }
  274. /**
  275. * Gets the passages for the given chapter from the server.
  276. * @param chapter Chapter to get passages for.
  277. */
  278. public void getPassages (Chapter chapter)
  279. {
  280. Integer chapterListId = chapter.getChapterListId ();
  281. JSONArray json = new JSONArray (this.m_Service.queryParam ("action", "getpassages")
  282. .queryParam ("chapterid", chapterListId.toString ())
  283. .accept (MediaType.APPLICATION_JSON)
  284. .get (String.class));
  285. int passageCount = json.length ();
  286. for (int i = 0; i < passageCount; i++) {
  287. JSONObject passageItem = json.getJSONObject (i);
  288. Passage passage = new Passage (passageItem.getInt ("passageid"),
  289. passageItem.getString ("passage"),
  290. passageItem.getInt ("passagenumber"),
  291. passageItem.getInt ("order"));
  292. JSONObject header = passageItem.optJSONObject ("header");
  293. if (header != null) {
  294. passage.setHeader (header.getInt ("id"), header.getString ("text"));
  295. }
  296. JSONArray footers = passageItem.optJSONArray ("footers");
  297. if (footers != null) {
  298. int footerCount = footers.length ();
  299. for (int j = 0; j < footerCount; j++) {
  300. JSONObject footerItem = footers.getJSONObject (j);
  301. passage.addFooter (footerItem.getInt ("id"), footerItem.getString ("footer"), footerItem.getInt ("index"));
  302. }
  303. }
  304. JSONObject links = passageItem.optJSONObject ("links");
  305. if (links != null) {
  306. for (Iterator it = links.keys (); it.hasNext ();) {
  307. String linkId = it.next ().toString ();
  308. JSONObject linkItem = links.getJSONObject (linkId);
  309. passage.addLink (Integer.parseInt (linkId), linkItem.getInt ("start"),
  310. linkItem.getInt ("end"), linkItem.getString ("area"),
  311. linkItem.getString ("link"));
  312. }
  313. }
  314. JSONObject definitions = passageItem.optJSONObject ("definitions");
  315. if (definitions != null) {
  316. for (Iterator it = definitions.keys (); it.hasNext ();) {
  317. String defid = it.next ().toString ();
  318. JSONObject defItem = definitions.getJSONObject (defid);
  319. passage.addDefinition (Integer.parseInt (defid), defItem.getInt ("start"),
  320. defItem.getInt ("end"), defItem.getString ("item"));
  321. }
  322. }
  323. JSONObject styles = passageItem.optJSONObject ("styles");
  324. if (styles != null) {
  325. for (Iterator it = styles.keys (); it.hasNext ();) {
  326. String passageStyleId = it.next ().toString ();
  327. JSONObject styleItem = styles.getJSONObject (passageStyleId);
  328. passage.addStyle (Integer.parseInt (passageStyleId), styleItem.getInt ("start"),
  329. styleItem.getInt ("end"), styleItem.getInt ("styleid"),
  330. styleItem.getInt ("styletypeid"), styleItem.optString ("style"));
  331. }
  332. }
  333. chapter.getPassages ().add (passage);
  334. }
  335. }
  336. }