/driver/src/main/com/mongodb/util/JSONCallback.java

http://github.com/mongodb/mongo-java-driver · Java · 149 lines · 113 code · 15 blank · 21 comment · 35 complexity · f03f6566541747fbf6fc15f7e2aced53 MD5 · raw file

  1. /*
  2. * Copyright (c) 2008-2014 MongoDB, Inc.
  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. // JSONCallback.java
  17. package com.mongodb.util;
  18. import com.mongodb.BasicDBList;
  19. import com.mongodb.BasicDBObject;
  20. import com.mongodb.DBObject;
  21. import com.mongodb.DBRef;
  22. import org.bson.BSON;
  23. import org.bson.BSONObject;
  24. import org.bson.BasicBSONCallback;
  25. import org.bson.BsonUndefined;
  26. import org.bson.types.BSONTimestamp;
  27. import org.bson.types.Binary;
  28. import org.bson.types.Code;
  29. import org.bson.types.CodeWScope;
  30. import org.bson.types.MaxKey;
  31. import org.bson.types.MinKey;
  32. import org.bson.types.ObjectId;
  33. import javax.xml.bind.DatatypeConverter;
  34. import java.text.ParsePosition;
  35. import java.text.SimpleDateFormat;
  36. import java.util.Date;
  37. import java.util.GregorianCalendar;
  38. import java.util.SimpleTimeZone;
  39. import java.util.UUID;
  40. import java.util.regex.Pattern;
  41. /**
  42. * Converts JSON to DBObjects and vice versa.
  43. */
  44. public class JSONCallback extends BasicBSONCallback {
  45. @Override
  46. public BSONObject create() {
  47. return new BasicDBObject();
  48. }
  49. @Override
  50. protected BSONObject createList() {
  51. return new BasicDBList();
  52. }
  53. @Override
  54. public void arrayStart(final String name) {
  55. _lastArray = true;
  56. super.arrayStart(name);
  57. }
  58. @Override
  59. public void objectStart(final String name) {
  60. _lastArray = false;
  61. super.objectStart(name);
  62. }
  63. @Override
  64. public Object objectDone() {
  65. String name = curName();
  66. Object o = super.objectDone();
  67. if (_lastArray) {
  68. return o;
  69. }
  70. BSONObject b = (BSONObject) o;
  71. // override the object if it's a special type
  72. if (b.containsField("$oid")) {
  73. o = new ObjectId((String) b.get("$oid"));
  74. } else if (b.containsField("$date")) {
  75. if (b.get("$date") instanceof Number) {
  76. o = new Date(((Number) b.get("$date")).longValue());
  77. } else {
  78. SimpleDateFormat format = new SimpleDateFormat(_msDateFormat);
  79. format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
  80. o = format.parse(b.get("$date").toString(), new ParsePosition(0));
  81. if (o == null) {
  82. // try older format with no ms
  83. format = new SimpleDateFormat(_secDateFormat);
  84. format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
  85. o = format.parse(b.get("$date").toString(), new ParsePosition(0));
  86. }
  87. }
  88. } else if (b.containsField("$regex")) {
  89. o = Pattern.compile((String) b.get("$regex"),
  90. BSON.regexFlags((String) b.get("$options")));
  91. } else if (b.containsField("$ts")) { //Legacy timestamp format
  92. Integer ts = ((Number) b.get("$ts")).intValue();
  93. Integer inc = ((Number) b.get("$inc")).intValue();
  94. o = new BSONTimestamp(ts, inc);
  95. } else if (b.containsField("$timestamp")) {
  96. BSONObject tsObject = (BSONObject) b.get("$timestamp");
  97. Integer ts = ((Number) tsObject.get("t")).intValue();
  98. Integer inc = ((Number) tsObject.get("i")).intValue();
  99. o = new BSONTimestamp(ts, inc);
  100. } else if (b.containsField("$code")) {
  101. if (b.containsField("$scope")) {
  102. o = new CodeWScope((String) b.get("$code"), (DBObject) b.get("$scope"));
  103. } else {
  104. o = new Code((String) b.get("$code"));
  105. }
  106. } else if (b.containsField("$ref")) {
  107. o = new DBRef((String) b.get("$ref"), b.get("$id"));
  108. } else if (b.containsField("$minKey")) {
  109. o = new MinKey();
  110. } else if (b.containsField("$maxKey")) {
  111. o = new MaxKey();
  112. } else if (b.containsField("$uuid")) {
  113. o = UUID.fromString((String) b.get("$uuid"));
  114. } else if (b.containsField("$binary")) {
  115. int type = (Integer) b.get("$type");
  116. byte[] bytes = DatatypeConverter.parseBase64Binary((String) b.get("$binary"));
  117. o = new Binary((byte) type, bytes);
  118. } else if (b.containsField("$undefined") && b.get("$undefined").equals(true)) {
  119. o = new BsonUndefined();
  120. } else if (b.containsField("$numberLong")) {
  121. o = Long.valueOf((String) b.get("$numberLong"));
  122. }
  123. if (!isStackEmpty()) {
  124. _put(name, o);
  125. } else {
  126. o = !BSON.hasDecodeHooks() ? o : BSON.applyDecodingHooks(o);
  127. setRoot(o);
  128. }
  129. return o;
  130. }
  131. private boolean _lastArray = false;
  132. public static final String _msDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  133. public static final String _secDateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
  134. }