PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/core/infinit.e.data_model/src/com/ikanow/infinit/e/data_model/api/knowledge/DocumentPojoApiMap.java

https://github.com/IKANOW/Infinit.e
Java | 209 lines | 154 code | 18 blank | 37 comment | 43 complexity | f143b841b6a63d59793dcc18c1982ab3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*******************************************************************************
  2. * Copyright 2012 The Infinit.e Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. ******************************************************************************/
  16. package com.ikanow.infinit.e.data_model.api.knowledge;
  17. import java.lang.reflect.Type;
  18. import java.util.Map.Entry;
  19. import org.bson.types.ObjectId;
  20. import com.google.gson.GsonBuilder;
  21. import com.google.gson.JsonArray;
  22. import com.google.gson.JsonDeserializationContext;
  23. import com.google.gson.JsonDeserializer;
  24. import com.google.gson.JsonElement;
  25. import com.google.gson.JsonObject;
  26. import com.google.gson.JsonParseException;
  27. import com.google.gson.JsonPrimitive;
  28. import com.google.gson.JsonSerializationContext;
  29. import com.google.gson.JsonSerializer;
  30. import com.ikanow.infinit.e.data_model.api.BaseApiPojo;
  31. import com.ikanow.infinit.e.data_model.api.BasePojoApiMap;
  32. import com.ikanow.infinit.e.data_model.store.MongoDbUtil;
  33. import com.ikanow.infinit.e.data_model.store.document.DocumentPojo;
  34. import com.mongodb.BasicDBList;
  35. import com.mongodb.BasicDBObject;
  36. public class DocumentPojoApiMap implements BasePojoApiMap<DocumentPojo> {
  37. public GsonBuilder extendBuilder(GsonBuilder gp) {
  38. return gp.registerTypeAdapter(DocumentPojo.class, new DocumentPojoSerializer())
  39. .registerTypeAdapter(DocumentPojo.class, new DocumentPojoDeserializer());
  40. }
  41. // Tidy up document pojo from DB format to API format (few slight differences, see DocumentPojo)
  42. protected static class DocumentPojoSerializer implements JsonSerializer<DocumentPojo>
  43. {
  44. @Override
  45. public JsonElement serialize(DocumentPojo doc, Type typeOfT, JsonSerializationContext context)
  46. {
  47. // 1. On the document side: remove the internal index reference, other internal fields
  48. doc.setIndex(null);
  49. // (locs, months, timeRanges not stored in DB so no need to remove)
  50. // 1b. Also on the doc side: switch the update id and _id
  51. ObjectId updateId = doc.getUpdateId();
  52. if (null != updateId) {
  53. doc.setUpdateId(doc.getId()); // (store the old _id mostly for diagnosis)
  54. doc.setId(updateId); // this makes the _id field immutable across updates
  55. }
  56. // Everything else needs to be done on the JSON side:
  57. JsonElement je = BaseApiPojo.getDefaultBuilder().create().toJsonTree(doc, typeOfT);
  58. JsonObject jo = je.getAsJsonObject();
  59. JsonElement jetmp = null;
  60. // 2. Source title should be an array:
  61. jetmp = jo.get(DocumentPojo.source_);
  62. if (null != jetmp) {
  63. JsonArray ja = new JsonArray();
  64. ja.add(jetmp);
  65. jo.add(DocumentPojo.source_, ja);
  66. }
  67. // 3. Source keys should be an array:
  68. jetmp = jo.get(DocumentPojo.sourceKey_);
  69. // (also the <key>#<format> should be reduced back to <key>)
  70. if (null != jetmp) {
  71. String sourceKey = jetmp.getAsString();
  72. if (null != sourceKey) {
  73. int nCommunityIndex = 0;
  74. if (-1 != (nCommunityIndex = sourceKey.indexOf('#'))) {
  75. sourceKey = sourceKey.substring(0, nCommunityIndex);
  76. jetmp = new JsonPrimitive(sourceKey);
  77. }
  78. }
  79. JsonArray ja = new JsonArray();
  80. ja.add(jetmp);
  81. jo.add(DocumentPojo.sourceKey_, ja);
  82. }
  83. // 4. Media types should be an array:
  84. jetmp = jo.get(DocumentPojo.mediaType_);
  85. if (null != jetmp) {
  86. JsonArray ja = new JsonArray();
  87. ja.add(jetmp);
  88. jo.add(DocumentPojo.mediaType_, ja);
  89. }
  90. // 5. Finally, CommunityId becomes an array
  91. jetmp = jo.get(DocumentPojo.communityId_);
  92. if (null != jetmp) {
  93. JsonArray ja = new JsonArray();
  94. ja.add(jetmp);
  95. jo.add(DocumentPojo.communityId_, ja);
  96. }
  97. return jo;
  98. }//TESTED (see DOC_API2 in TestCode)
  99. }
  100. // The same functionality as the above function but operates on the raw BasicDBObject
  101. // for performance
  102. public static void mapToApi(BasicDBObject doc) {
  103. // 1. (doc_index field)
  104. doc.remove(DocumentPojo.index_);
  105. // 2. (source title)
  106. String tmp = doc.getString(DocumentPojo.source_);
  107. if (null != tmp) {
  108. BasicDBList array = new BasicDBList();
  109. array.add(tmp);
  110. doc.put(DocumentPojo.source_, array);
  111. }
  112. // 3. (source key)
  113. tmp = doc.getString(DocumentPojo.sourceKey_);
  114. if (null != tmp) {
  115. int nCommunityIndex = 0;
  116. if (-1 != (nCommunityIndex = tmp.indexOf('#'))) {
  117. tmp = tmp.substring(0, nCommunityIndex);
  118. }
  119. BasicDBList array = new BasicDBList();
  120. array.add(tmp);
  121. doc.put(DocumentPojo.sourceKey_, array);
  122. }
  123. // 4. (media type)
  124. tmp = doc.getString(DocumentPojo.mediaType_);
  125. if (null != tmp) {
  126. BasicDBList array = new BasicDBList();
  127. array.add(tmp);
  128. doc.put(DocumentPojo.mediaType_, array);
  129. }
  130. }//TESTED (see DOC_API1 in TestCode)
  131. protected static class DocumentPojoDeserializer implements JsonDeserializer<DocumentPojo>
  132. {
  133. public DocumentPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
  134. {
  135. // We have converted many of the fields into arrays, we need to transform them back to single values
  136. // (we will have to discard the 2nd+ fields in each array - this call is only used for testing so we can live
  137. // with that)
  138. JsonElement tmp = json.getAsJsonObject().get(DocumentPojo.source_);
  139. if ((null != tmp) && (tmp.isJsonArray())) {
  140. JsonArray tmpArray = tmp.getAsJsonArray();
  141. JsonElement singleVal = tmpArray.get(0);
  142. json.getAsJsonObject().add(DocumentPojo.source_, singleVal);
  143. }
  144. tmp = json.getAsJsonObject().get(DocumentPojo.sourceKey_);
  145. if ((null != tmp) && (tmp.isJsonArray())) {
  146. JsonArray tmpArray = tmp.getAsJsonArray();
  147. JsonElement singleVal = tmpArray.get(0);
  148. json.getAsJsonObject().add(DocumentPojo.sourceKey_, singleVal);
  149. }
  150. tmp = json.getAsJsonObject().get(DocumentPojo.mediaType_);
  151. if ((null != tmp) && (tmp.isJsonArray())) {
  152. JsonArray tmpArray = tmp.getAsJsonArray();
  153. JsonElement singleVal = tmpArray.get(0);
  154. json.getAsJsonObject().add(DocumentPojo.mediaType_, singleVal);
  155. }
  156. tmp = json.getAsJsonObject().get(DocumentPojo.communityId_);
  157. if ((null != tmp) && (tmp.isJsonArray())) {
  158. JsonArray tmpArray = tmp.getAsJsonArray();
  159. JsonElement singleVal = tmpArray.get(0);
  160. json.getAsJsonObject().add(DocumentPojo.communityId_, singleVal);
  161. }
  162. // Finally sort out metadata...
  163. tmp = json.getAsJsonObject().get(DocumentPojo.metadata_);
  164. if (null != tmp) {
  165. json.getAsJsonObject().remove(DocumentPojo.metadata_);
  166. }
  167. DocumentPojo doc = BaseApiPojo.getDefaultBuilder().create().fromJson(json, DocumentPojo.class);
  168. // ...And add metadata back again...
  169. if (null != tmp) {
  170. JsonObject tmpMeta = tmp.getAsJsonObject();
  171. for (Entry<String, JsonElement> entry: tmpMeta.entrySet()) {
  172. if (entry.getValue().isJsonArray()) {
  173. doc.addToMetadata(entry.getKey(), MongoDbUtil.encodeArray(entry.getValue().getAsJsonArray()));
  174. }
  175. else {
  176. BasicDBList dbl = new BasicDBList();
  177. dbl.add(MongoDbUtil.encodeUnknown(entry.getValue()));
  178. doc.addToMetadata(entry.getKey(), dbl);
  179. }
  180. }//TOTEST
  181. }
  182. // Finally handle updateId/_id swap
  183. ObjectId updateId = doc.getUpdateId();
  184. if (null != updateId) {
  185. doc.setUpdateId(doc.getId()); // (this is now the immutable _id)
  186. doc.setId(updateId); // this points to the _id in the DB
  187. }
  188. return doc;
  189. }//TESTED (by hand only, no formal record)
  190. }
  191. }