private static BasicBSONObject canonicalizeBSONObject(final BSONObject from) { final BasicBSONObject canonicalized = new BasicBSONObject(); final TreeSet<String> keysInOrder = new TreeSet<String>(from.keySet()); for (final String key : keysInOrder) { final Object val = from.get(key); canonicalized.put(key, canonicalize(val)); } return canonicalized; }
public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof BSONObject)) { return false; } final BSONObject other = (BSONObject) o; return ((HashMap<String, V>) this).keySet().equals(other.keySet()) && Arrays.equals( canonicalizeBSONObject(this).encode(), canonicalizeBSONObject(other).encode()); }
public Object objectDone() { Object o = super.objectDone(); BSONObject b = (BSONObject) o; if (!_lastArray) { if (b.containsField("$oid")) { o = new ObjectId((String) b.get("$oid")); if (!isStackEmpty()) { gotObjectId(_lastName, (ObjectId) o); } else { setRoot(o); } } else if (b.containsField("$date")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT"))); o = format.parse((String) b.get("$date"), new ParsePosition(0)); if (!isStackEmpty()) { cur().put(_lastName, o); } else { setRoot(o); } } else if (b.containsField("$regex")) { o = Pattern.compile((String) b.get("$regex"), BSON.regexFlags((String) b.get("$options"))); if (!isStackEmpty()) { cur().put(_lastName, o); } else { setRoot(o); } } } return o; }
@Test @SuppressWarnings("unchecked") public void testCustomEncoders() throws IOException { // If clearEncodingHooks isn't working the first test will fail. Transformer tf = new TestDateTransformer(); BSON.addEncodingHook(TestDate.class, tf); BSON.clearEncodingHooks(); TestDate td = new TestDate(2009, 01, 23, 10, 53, 42); BSONObject o = new BasicBSONObject("date", td); BSONEncoder e = new BasicBSONEncoder(); BSONDecoder d = new BasicBSONDecoder(); BSONCallback cb = new BasicBSONCallback(); OutputBuffer buf = new BasicOutputBuffer(); e.set(buf); boolean encodeFailed = false; try { e.putObject(o); } catch (IllegalArgumentException ieE) { encodeFailed = true; } assertTrue(encodeFailed); // Reset the buffer buf.seekStart(); assertTrue(tf.transform(td) instanceof java.util.Date); BSON.addEncodingHook(TestDate.class, tf); e.putObject(o); e.done(); d.decode(new ByteArrayInputStream(buf.toByteArray()), cb); Object result = cb.get(); assertTrue(result instanceof BSONObject); BSONObject bson = (BSONObject) result; assertNotNull(bson.get("date")); assertTrue(bson.get("date") instanceof java.util.Date); // Check that the hooks registered assertNotNull(BSON.getEncodingHooks(TestDate.class)); Vector expect = new Vector(1); expect.add(tf); assertEquals(BSON.getEncodingHooks(TestDate.class), expect); assertTrue(BSON.getEncodingHooks(TestDate.class).contains(tf)); BSON.removeEncodingHook(TestDate.class, tf); assertFalse(BSON.getEncodingHooks(TestDate.class).contains(tf)); }
@Test @SuppressWarnings({"deprecation", "unchecked"}) public void testCustomDecoders() throws IOException { // If clearDecodingHooks isn't working this whole test will fail. Transformer tf = new TestDateTransformer(); BSON.addDecodingHook(Date.class, tf); BSON.clearDecodingHooks(); TestDate td = new TestDate(2009, 01, 23, 10, 53, 42); Date dt = new Date(2009, 01, 23, 10, 53, 42); BSONObject o = new BasicBSONObject("date", dt); BSONDecoder d = new BasicBSONDecoder(); BSONEncoder e = new BasicBSONEncoder(); BSONCallback cb = new BasicBSONCallback(); OutputBuffer buf = new BasicOutputBuffer(); e.set(buf); e.putObject(o); e.done(); d.decode(new ByteArrayInputStream(buf.toByteArray()), cb); Object result = cb.get(); assertTrue(result instanceof BSONObject); BSONObject bson = (BSONObject) result; assertNotNull(bson.get("date")); assertTrue(bson.get("date") instanceof java.util.Date); BSON.addDecodingHook(Date.class, tf); d.decode(new ByteArrayInputStream(buf.toByteArray()), cb); bson = (BSONObject) cb.get(); assertNotNull(bson.get("date")); assertTrue(bson.get("date") instanceof TestDate); assertEquals(bson.get("date"), td); // Check that the hooks registered assertNotNull(BSON.getDecodingHooks(Date.class)); Vector expect = new Vector(1); expect.add(tf); assertEquals(BSON.getDecodingHooks(Date.class), expect); assertTrue(BSON.getDecodingHooks(Date.class).contains(tf)); BSON.removeDecodingHook(Date.class, tf); assertFalse(BSON.getDecodingHooks(Date.class).contains(tf)); }
public void putAll(final BSONObject o) { for (final String k : o.keySet()) { this.put(k, o.get(k)); } }
public Object objectDone() { String name = curName(); Object o = super.objectDone(); BSONObject b = (BSONObject) o; // override the object if it's a special type if (!_lastArray) { if (b.containsField("$oid")) { o = new ObjectId((String) b.get("$oid")); if (!isStackEmpty()) { gotObjectId(name, (ObjectId) o); } else { setRoot(o); } } else if (b.containsField("$date")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); GregorianCalendar calendar = new GregorianCalendar(new SimpleTimeZone(0, "GMT")); format.setCalendar(calendar); String txtdate = (String) b.get("$date"); o = format.parse(txtdate, new ParsePosition(0)); if (o == null) { // try older format with no ms format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); format.setCalendar(calendar); o = format.parse(txtdate, new ParsePosition(0)); } if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$regex")) { o = Pattern.compile((String) b.get("$regex"), BSON.regexFlags((String) b.get("$options"))); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$ts")) { Long ts = ((Number) b.get("$ts")).longValue(); Long inc = ((Number) b.get("$inc")).longValue(); o = new BSONTimestamp(ts.intValue(), inc.intValue()); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$code")) { if (b.containsField("$scope")) { o = new CodeWScope((String) b.get("$code"), (DBObject) b.get("$scope")); } else { o = new Code((String) b.get("$code")); } if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$ref")) { o = new DBRef(null, (String) b.get("$ref"), b.get("$id")); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$minKey")) { o = new MinKey(); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$maxKey")) { o = new MaxKey(); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } else if (b.containsField("$uuid")) { o = UUID.fromString((String) b.get("$uuid")); if (!isStackEmpty()) { cur().put(name, o); } else { setRoot(o); } } } return o; }
/** this is really for embedded objects */ int putObject(String name, BSONObject o) { if (o == null) throw new NullPointerException("can't save a null object"); if (DEBUG) System.out.println( "putObject : " + name + " [" + o.getClass() + "]" + " # keys " + o.keySet().size()); final int start = _buf.getPosition(); byte myType = OBJECT; if (o instanceof List) myType = ARRAY; if (handleSpecialObjects(name, o)) return _buf.getPosition() - start; if (name != null) { _put(myType, name); } final int sizePos = _buf.getPosition(); _buf.writeInt(0); // leaving space for this. set it at the end List transientFields = null; boolean rewriteID = myType == OBJECT && name == null; if (myType == OBJECT) { if (rewriteID && o.containsField("_id")) _putObjectField("_id", o.get("_id")); { Object temp = o.get("_transientFields"); if (temp instanceof List) transientFields = (List) temp; } } // TODO: reduce repeated code below. if (o instanceof Map) { for (Entry<String, Object> e : ((Map<String, Object>) o).entrySet()) { if (rewriteID && e.getKey().equals("_id")) continue; if (transientFields != null && transientFields.contains(e.getKey())) continue; _putObjectField(e.getKey(), e.getValue()); } } else { for (String s : o.keySet()) { if (rewriteID && s.equals("_id")) continue; if (transientFields != null && transientFields.contains(s)) continue; Object val = o.get(s); _putObjectField(s, val); } } _buf.write(EOO); _buf.writeInt(sizePos, _buf.getPosition() - sizePos); return _buf.getPosition() - start; }