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 <O> O instantiate(ClassTypeModel<O> typeModel, Map<FieldModel<? super O, ?>, ?> state) throws InvalidClassException { try { ObjectFactory<? super O> factory = context.getFactory(typeModel.getJavaType()); // return factory.create(typeModel.getJavaType(), state); } catch (Exception e) { InvalidClassException ice = new InvalidClassException( "Cannot instantiate object from class " + typeModel.getJavaType().getName()); ice.initCause(e); throw ice; } }