protected <O> O instantiate(int id, DataContainer container, ClassTypeModel<O> typeModel) throws IOException { Map<FieldModel<? super O, ?>, Object> state = new HashMap<FieldModel<? super O, ?>, Object>(); ClassTypeModel<? super O> currentTypeModel = typeModel; List<FieldUpdate<O>> sets = new ArrayList<FieldUpdate<O>>(); while (currentTypeModel != null) { if (currentTypeModel instanceof ClassTypeModel) { for (FieldModel<? super O, ?> fieldModel : currentTypeModel.getFields()) { if (!fieldModel.isTransient()) { switch (container.readInt()) { case DataKind.NULL_VALUE: state.put(fieldModel, null); break; case DataKind.OBJECT_REF: int refId = container.readInt(); Object refO = idToObject.get(refId); if (refO != null) { state.put(fieldModel, refO); } else { sets.add(new FieldUpdate<O>(refId, fieldModel)); } break; case DataKind.OBJECT: Object o = container.readObject(); state.put(fieldModel, o); break; } } } } currentTypeModel = currentTypeModel.getSuperType(); } // O instance = instantiate(typeModel, state); // Create future field updates for (FieldUpdate<O> set : sets) { List<FutureFieldUpdate<?>> resolutions = idToResolutions.get(set.ref); if (resolutions == null) { resolutions = new ArrayList<FutureFieldUpdate<?>>(); idToResolutions.put(set.ref, resolutions); } resolutions.add(new FutureFieldUpdate<O>(instance, set.fieldModel)); } // idToObject.put(id, instance); // Resolve future field updates List<FutureFieldUpdate<?>> resolutions = idToResolutions.remove(id); if (resolutions != null) { for (FutureFieldUpdate<?> resolution : resolutions) { resolution.fieldModel.castAndSet(resolution.target, instance); } } // return instance; }
private Object read(DataContainer container) throws IOException { int sw = container.readInt(); switch (sw) { case DataKind.OBJECT_REF: { int id = container.readInt(); Object o1 = idToObject.get(id); if (o1 == null) { throw new AssertionError(); } return o1; } case DataKind.OBJECT: { int id = container.readInt(); Class<?> clazz = (Class) container.readObject(); ClassTypeModel<?> typeModel = (ClassTypeModel<?>) context.getTypeDomain().getTypeModel(clazz); return instantiate(id, container, typeModel); } case DataKind.CONVERTED_OBJECT: { Class<?> tclazz = (Class<?>) container.readObject(); ConvertedTypeModel<?, ?> ctm = (ConvertedTypeModel<?, ?>) context.getTypeDomain().getTypeModel(tclazz); return convertObject(container, ctm); } case DataKind.SERIALIZED_OBJECT: return container.readObject(); default: throw new StreamCorruptedException("Unrecognized data " + sw); } }