private void traceFields(LinkedList<Object> stack, Object obj) { ClassMeta fields = getDeepDeclaredFields(obj.getClass()); for (Field field : fields.values()) { try { if (isPrimitiveWrapper( field .getType())) { // speed up: primitives & primitive wrappers cannot reference another // object continue; } Object o = field.get(obj); if (o != null) { stack.addFirst(o); } } catch (IllegalAccessException ignored) { } } }
/** * String, Date, and Class have been written before calling this method, strictly for performance. * * @param obj Object to be written in JSON format * @param showType boolean true means show the "@type" field, false eliminates it. Many times the * type can be dropped because it can be inferred from the field or array type. * @throws IOException if an error occurs writing to the output stream. */ private void writeObject(Object obj, boolean showType) throws IOException { if (obj instanceof String) { writeJsonUtf8String((String) obj); return; } else if (obj.getClass().equals(Date.class)) { writeDate(obj, showType); return; } else if (obj instanceof Class) { writeClass(obj, showType); return; } if (writeOptionalReference(obj)) { return; } if (obj instanceof Calendar) { Calendar cal = (Calendar) obj; _dateFormat.setTimeZone(cal.getTimeZone()); String date = _dateFormat.format(cal.getTime()); writeSpecial(obj, showType, date); return; } else if (obj instanceof BigDecimal) { writeSpecial(obj, showType, ((BigDecimal) obj).toPlainString()); return; } else if (obj instanceof BigInteger) { writeSpecial(obj, showType, obj.toString()); return; } else if (obj instanceof java.sql.Date) { writeSpecial(obj, showType, obj.toString()); return; } _out.write('{'); boolean referenced = _objsReferenced.containsKey(obj); if (referenced) { writeId(getId(obj)); } ClassMeta classInfo = getDeepDeclaredFields(obj.getClass()); if (classInfo._writeMethod != null) { // Must show type when class has custom _writeJson() method on it. // The JsonReader uses this to know it is dealing with an object // that has custom json io methods on it. showType = true; } if (referenced && showType) { _out.write(','); } if (showType) { writeType(obj); } boolean first = !showType; if (referenced && !showType) { first = false; } if (classInfo._writeMethod == null) { for (Field field : classInfo.values()) { if (_prettyMode && (field.getModifiers() & Modifier.TRANSIENT) != 0) { // Skip transient fields when in 'prettyMode' continue; } if (first) { first = false; } else { _out.write(','); } writeJsonUtf8String(field.getName()); _out.write(':'); Object o; try { o = field.get(obj); } catch (IllegalAccessException e) { o = null; } if (o == null) { // don't quote null _out.write("null"); continue; } Class type = field.getType(); boolean forceType = o.getClass() != type; // If types are not exactly the same, write "@type" field if (isPrimitiveWrapper(type)) { writePrimitive(o); } else { writeImpl(o, forceType); } } } else { // Invoke custom _writeJson() method. _out.write(','); try { classInfo._writeMethod.invoke(obj, _out); } catch (Exception e) { throw new IOException("Error invoking " + obj.getClass() + "._jsonWrite()", e); } } _out.write('}'); }