}
case ID_PREDEFINED_EXTERNALIZER_CLASS: {
final int idx = classCache.size();
classCache.add(null);
final Class<?> type = classTable.readClass(this);
final Externalizer externalizer = (Externalizer) readObject();
final SimpleClassDescriptor descriptor = new ExternalizerClassDescriptor(type, externalizer);
classCache.set(idx, descriptor);
return descriptor;
}
case ID_PREDEFINED_PLAIN_CLASS: {
final int idx = classCache.size();
classCache.add(null);
final Class<?> type = classTable.readClass(this);
final SimpleClassDescriptor descriptor = new SimpleClassDescriptor(type, ID_PLAIN_CLASS);
classCache.set(idx, descriptor);
return descriptor;
}
case ID_PREDEFINED_PROXY_CLASS: {
final int idx = classCache.size();
classCache.add(null);
final Class<?> type = classTable.readClass(this);
final SimpleClassDescriptor descriptor = new SimpleClassDescriptor(type, ID_PROXY_CLASS);
classCache.set(idx, descriptor);
return descriptor;
}
case ID_PREDEFINED_SERIALIZABLE_CLASS: {
final int idx = classCache.size();
classCache.add(null);
final Class<?> type = classTable.readClass(this);
final SerializableClass serializableClass = registry.lookup(type);
int descType = serializableClass.hasWriteObject() ? ID_WRITE_OBJECT_CLASS : ID_SERIALIZABLE_CLASS;
final ClassDescriptor descriptor = new BasicSerializableClassDescriptor(serializableClass, doReadClassDescriptor(readUnsignedByte(), true), serializableClass.getFields(), descType);
classCache.set(idx, descriptor);
return descriptor;
}
case ID_PLAIN_CLASS: {
final String className = readString();
final Class<?> clazz = classResolver.resolveClass(this, className, 0L);
final SimpleClassDescriptor descriptor = new SimpleClassDescriptor(clazz, ID_PLAIN_CLASS);
classCache.add(descriptor);
return descriptor;
}
case ID_PROXY_CLASS: {
String[] interfaces = new String[readInt()];
for (int i = 0; i < interfaces.length; i ++) {
interfaces[i] = readString();
}
final int idx = classCache.size();
classCache.add(null);
final SimpleClassDescriptor descriptor = new SimpleClassDescriptor(classResolver.resolveProxyClass(this, interfaces), ID_PROXY_CLASS);
classCache.set(idx, descriptor);
return descriptor;
}
case ID_WRITE_OBJECT_CLASS:
case ID_SERIALIZABLE_CLASS: {
int idx = classCache.size();
classCache.add(null);
final String className = readString();
final long uid = readLong();
Class<?> clazz = null;
try {
clazz = classResolver.resolveClass(this, className, uid);
} catch (ClassNotFoundException cnfe) {
if (required) throw cnfe;
}
final FutureSerializableClassDescriptor descriptor = new FutureSerializableClassDescriptor(clazz, classType);
classCache.set(idx, descriptor);
final int cnt = readInt();
final String[] names = new String[cnt];
final ClassDescriptor[] descriptors = new ClassDescriptor[cnt];
final boolean[] unshareds = new boolean[cnt];
for (int i = 0; i < cnt; i ++) {
names[i] = readUTF();
descriptors[i] = doReadClassDescriptor(readUnsignedByte(), true);
unshareds[i] = readBoolean();
}
ClassDescriptor superDescriptor = doReadClassDescriptor(readUnsignedByte(), false);
final Class<?> superClazz = clazz == null ? superDescriptor.getNearestType() : clazz.getSuperclass();
if (superDescriptor != null) {
final Class<?> superType = superDescriptor.getNearestType();
if (clazz != null && ! superType.isAssignableFrom(clazz)) {
throw new InvalidClassException(clazz.getName(), "Class does not extend stream superclass");
}
Class<?> cl = superClazz;
while (cl != superType) {
superDescriptor = new SerializableGapClassDescriptor(registry.lookup(cl), superDescriptor);
cl = cl.getSuperclass();
}
} else if (superClazz != null) {
Class<?> cl = superClazz;
while (serializabilityChecker.isSerializable(cl)) {
superDescriptor = new SerializableGapClassDescriptor(registry.lookup(cl), superDescriptor);
cl = cl.getSuperclass();
}
}
final SerializableClass serializableClass;
final SerializableField[] fields = new SerializableField[cnt];
if (clazz != null) {
serializableClass = registry.lookup(clazz);
for (int i = 0; i < cnt; i ++) {
fields[i] = serializableClass.getSerializableField(names[i], descriptors[i].getType(), unshareds[i]);
}
} else {
serializableClass = null;
for (int i = 0; i < cnt; i ++) {
fields[i] = new SerializableField(descriptors[i].getType(), names[i], unshareds[i]);
}
}
descriptor.setResult(new BasicSerializableClassDescriptor(serializableClass, superDescriptor, fields, classType));
return descriptor;
}
case ID_EXTERNALIZABLE_CLASS: {
final String className = readString();
final long uid = readLong();
final Class<?> clazz = classResolver.resolveClass(this, className, uid);
final SimpleClassDescriptor descriptor = new SimpleClassDescriptor(clazz, ID_EXTERNALIZABLE_CLASS);
classCache.add(descriptor);
return descriptor;
}
case ID_EXTERNALIZER_CLASS: {
final String className = readString();
int idx = classCache.size();
classCache.add(null);
final Class<?> clazz = classResolver.resolveClass(this, className, 0L);
final Externalizer externalizer = (Externalizer) readObject();
final SimpleClassDescriptor descriptor = new ExternalizerClassDescriptor(clazz, externalizer);
classCache.set(idx, descriptor);
return descriptor;
}