if (getSerializationPolicy() instanceof TypeNameObfuscator) {
TypeNameObfuscator obfuscator = (TypeNameObfuscator) getSerializationPolicy();
String instanceClassName = obfuscator.getClassNameForTypeId(typeSignature);
instanceClass = Class.forName(instanceClassName, false, classLoader);
} else {
throw new SerializationException(
"The GWT module was compiled with RPC type name elision enabled, but "
+ getSerializationPolicy().getClass().getName() + " does not implement "
+ TypeNameObfuscator.class.getName());
}
} else {
SerializedInstanceReference serializedInstRef =
SerializabilityUtil.decodeSerializedInstanceReference(typeSignature);
instanceClass = Class.forName(serializedInstRef.getName(), false, classLoader);
validateTypeVersions(instanceClass, serializedInstRef);
}
if (resolvedTypes == null) {
// We can find ourselves with a null resolvedTypes map if a class
// has a non-type-checking serializer that tries to deserialize a field.
// In such cases there is field type information from the class, but no
// resolvedTypes because we did not pass it through the non-type
// checking serializer. Create a map, so that from this point forward
// we have some way of type checking.
resolvedTypes = new DequeMap<TypeVariable<?>, Type>();
}
// Try to determine the type for the generic type parameters of the
// instance class, based upon the expected type and any class hierarchy
// type information.
// In looking for the expected parameter types, we also find out the
// way in which the instance meets the expected type, and hence can find
// out when it does not meet expectations.
TypeVariable<?>[] instanceParameterTypes = instanceClass.getTypeParameters();
Type[] expectedParameterTypes = null;
if (expectedType != null) {
SerializabilityUtil.resolveTypes(expectedType, resolvedTypes);
expectedParameterTypes = SerializabilityUtil.findExpectedParameterTypes(
instanceClass, expectedType, resolvedTypes);
if (expectedParameterTypes == null) {
throw new SerializedTypeViolationException("Attempt to deserialize an object of type "
+ instanceClass.toString() + " when an object of type "
+ SerializabilityUtil.findActualType(expectedType, resolvedTypes).toString()
+ " is expected");
}
// Add mappings from the instance type variables to the resolved types
// map.
for (int i = 0; i < instanceParameterTypes.length; ++i) {
resolvedTypes.add(instanceParameterTypes[i], expectedParameterTypes[i]);
}
}
assert (serializationPolicy != null);
serializationPolicy.validateDeserialize(instanceClass);
Class<?> customSerializer = SerializabilityUtil.hasServerCustomFieldSerializer(instanceClass);
int index = reserveDecodedObjectIndex();
instance = instantiate(customSerializer, instanceClass, expectedParameterTypes,
resolvedTypes);
rememberDecodedObject(index, instance);
Object replacement = deserializeImpl(customSerializer, instanceClass, instance, expectedType,
expectedParameterTypes, resolvedTypes);
// Remove resolved types that were added for this instance.
if (expectedParameterTypes != null) {
for (int i = 0; i < instanceParameterTypes.length; ++i) {
resolvedTypes.remove(instanceParameterTypes[i]);
}
}
SerializabilityUtil.releaseTypes(expectedType, resolvedTypes);
// It's possible that deserializing an object requires the original proxy
// object to be replaced.
if (instance != replacement) {
rememberDecodedObject(index, replacement);
instance = replacement;
}
return instance;
} catch (ClassNotFoundException e) {
throw new SerializationException(e);
} catch (InstantiationException e) {
throw new SerializationException(e);
} catch (IllegalAccessException e) {
throw new SerializationException(e);
} catch (IllegalArgumentException e) {
throw new SerializationException(e);
} catch (InvocationTargetException e) {
throw new SerializationException(e.getTargetException());
} catch (NoSuchMethodException e) {
throw new SerializationException(e);
}
}