📄 serializableconverter.java
字号:
// Special case for objects that have readObject(), but not writeObject(). // The class wrapper is always written, whether or not this class in the hierarchy has // serializable fields. This guarantees that readObject() will be called upon deserialization. writtenClassWrapper[0] = true; writer.startNode(mapper.serializedClass(currentType[0])); callback.defaultWriteObject(); writer.endNode(); } else { writtenClassWrapper[0] = false; callback.defaultWriteObject(); if (writtenClassWrapper[0]) { writer.endNode(); } } } } catch (IOException e) { throw new ObjectAccessException("Could not call defaultWriteObject()", e); } } private Object readField(ObjectStreamField field, Class type, Object instance) { try { Field javaField = type.getDeclaredField(field.getName()); javaField.setAccessible(true); return javaField.get(instance); } catch (IllegalArgumentException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); } catch (IllegalAccessException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); } catch (NoSuchFieldException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); } catch (SecurityException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); } } private Iterator hierarchyFor(Class type) { List result = new ArrayList(); while(type != null) { result.add(type); type = type.getSuperclass(); } // In Java Object Serialization, the classes are deserialized starting from parent class and moving down. Collections.reverse(result); return result.iterator(); } public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { String resolvesAttribute = reader.getAttribute(mapper.attributeForReadResolveField()); Class requiredType; if (resolvesAttribute != null) { requiredType = mapper.realClass(resolvesAttribute); } else { requiredType = context.getRequiredType(); } final Object result = reflectionProvider.newInstance(requiredType); // this is an array as it's a non final value that's accessed from an anonymous inner class. final Class[] currentType = new Class[1]; if (!ATTRIBUTE_VALUE_CUSTOM.equals(reader.getAttribute(ATTRIBUTE_SERIALIZATION))) { throw new ConversionException("Cannot deserialize object with new readObject()/writeObject() methods"); } CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { public Object readFromStream() { reader.moveDown(); Class type = mapper.realClass(reader.getNodeName()); Object value = context.convertAnother(result, type); reader.moveUp(); return value; } public Map readFieldsFromStream() { Map result = new HashMap(); reader.moveDown(); if (reader.getNodeName().equals(ELEMENT_FIELDS)) { // Maintain compatability with XStream 1.1.0 while (reader.hasMoreChildren()) { reader.moveDown(); if (!reader.getNodeName().equals(ELEMENT_FIELD)) { throw new ConversionException("Expected <" + ELEMENT_FIELD + "/> element inside <" + ELEMENT_FIELD + "/>"); } String name = reader.getAttribute(ATTRIBUTE_NAME); Class type = mapper.realClass(reader.getAttribute(ATTRIBUTE_CLASS)); Object value = context.convertAnother(result, type); result.put(name, value); reader.moveUp(); } } else if (reader.getNodeName().equals(ELEMENT_DEFAULT)) { // New format introduced in XStream 1.1.1 ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); while (reader.hasMoreChildren()) { reader.moveDown(); String name = reader.getNodeName(); String typeName = reader.getAttribute(ATTRIBUTE_CLASS); Class type; if (typeName != null) { type = mapper.realClass(typeName); } else { ObjectStreamField field = objectStreamClass.getField(name); if (field == null) { throw new ObjectAccessException("Class " + currentType[0] + " does not contain a field named '" + name + "'"); } type = field.getType(); } Object value = context.convertAnother(result, type); result.put(name, value); reader.moveUp(); } } else { throw new ConversionException("Expected <" + ELEMENT_FIELDS + "/> or <" + ELEMENT_DEFAULT + "/> element when calling ObjectInputStream.readFields()"); } reader.moveUp(); return result; } public void defaultReadObject() { if (!reader.hasMoreChildren()) { return; } reader.moveDown(); if (!reader.getNodeName().equals(ELEMENT_DEFAULT)) { throw new ConversionException("Expected <" + ELEMENT_DEFAULT + "/> element in readObject() stream"); } while (reader.hasMoreChildren()) { reader.moveDown(); Class type; String fieldName = mapper.realMember(currentType[0], reader.getNodeName()); String classAttribute = reader.getAttribute(ATTRIBUTE_CLASS); if (classAttribute != null) { type = mapper.realClass(classAttribute); } else { type = mapper.defaultImplementationOf(reflectionProvider.getFieldType(result, fieldName, currentType[0])); } Object value = context.convertAnother(result, type); reflectionProvider.writeField(result, fieldName, value, currentType[0]); reader.moveUp(); } reader.moveUp(); } public void registerValidation(final ObjectInputValidation validation, int priority) { context.addCompletionCallback(new Runnable() { public void run() { try { validation.validateObject(); } catch (InvalidObjectException e) { throw new ObjectAccessException("Cannot validate object : " + e.getMessage(), e); } } }, priority); } public void close() { throw new UnsupportedOperationException("Objects are not allowed to call ObjectInputStream.close() from readObject()"); } }; while (reader.hasMoreChildren()) { reader.moveDown(); currentType[0] = mapper.defaultImplementationOf(mapper.realClass(reader.getNodeName())); if (serializationMethodInvoker.supportsReadObject(currentType[0], false)) { ObjectInputStream objectInputStream = CustomObjectInputStream.getInstance(context, callback); serializationMethodInvoker.callReadObject(currentType[0], result, objectInputStream); } else { try { callback.defaultReadObject(); } catch (IOException e) { throw new ObjectAccessException("Could not call defaultWriteObject()", e); } } reader.moveUp(); } return serializationMethodInvoker.callReadResolve(result); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -