📄 xmlobjectinputstream.java
字号:
* @throws ClassNotFoundException If the class cannot be found * @throws NotSerializableException If the class to be deserialized is not * Serializable */ protected Object readOrdinaryObject(boolean shared) throws IOException, ClassNotFoundException { reader.assertStartTag("object"); Class c = Class.forName(reader.getAttribute("class")); String id = reader.getAttribute("id"); if (!Serializable.class.isAssignableFrom(c)) { throw new NotSerializableException(c.getName()); } Object o = newInstance(c); if (shared && (id != null)) { putReference(id, o); } if (Externalizable.class.isAssignableFrom(c)) { ((Externalizable) o).readExternal(this); reader.step(); } else { reader.step(); while (!reader.isEndTag()) { readClass(o); reader.step(); } } reader.assertEndTag("object"); Method method = getReadResolve(c); try { if (method != null) { o = method.invoke(o, new Object[0]); if (shared && (id != null)) { putReference(id, o); } } } catch (IllegalAccessException e) { throw new IOException("ReadResolve caused " + e); } catch (InvocationTargetException e) { throw new IOException("ReadResolve caused " + e); } return o; } /** * Method which reads the information for one class for a given object from * the stream. This method assumes that the XML reader is currently on a start * declaredClass tag, and does consume the corresponding end declaredClass * tag. This method first reads the class type, and if it defines a * readObject() method, it is called. Otherwise, the fields are read in a * default manner. Any extra data not read in the stream is read and ignored. * * @param o The object we are reading the the class for * @return The object read from the stream * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected Object readClass(Object o) throws IOException, ClassNotFoundException { reader.assertStartTag("declaredClass"); Class c = Class.forName(reader.getAttribute("class")); Method method = getReadObject(c); if (method != null) { try { currentObjects.push(o); currentClasses.push(c); method.invoke(o, new Object[]{this}); currentObjects.pop(); currentClasses.pop(); readUnreadOptionalData(); } catch (InvocationTargetException e) { System.out.println(e.getTargetException().getMessage()); e.getTargetException().printStackTrace(); throw new IOException("InvocationTargetException thrown! " + e.getTargetException()); } catch (IllegalAccessException e) { System.out.println(e.getMessage()); e.printStackTrace(); throw new IOException("IllegalAccessException thrown! " + e); } } else { readFields(o, c); readUnreadOptionalData(); } reader.assertEndTag("declaredClass"); return o; } /** * Method which reads any extra data from the stream which was not read by the * object. This method simply loops until it hits the appropriate end * declaredClass tag, and then returns. Thus, any data read by this method is * ignored. However, the objects here are deserialized as the stream may * reference them in the future. * * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected void readUnreadOptionalData() throws IOException, ClassNotFoundException { reader.step(); while (!reader.isEndTag()) { if (reader.getStartTag().equals("primitive")) { reader.readEndTag("primitive"); } else if (reader.getStartTag().equals("base64")) { reader.readEndTag("base64"); } else { readObjectHelper(); } reader.step(); } } /** * Method which reads all of the field data from the stream, as readFields() * does, but instead of assigning the fields to the object, it returns them as * a GetField object. In this manner, the object itself can perform field * inititalization. * * @return The fields read from the stream * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected GetField readGetFields() throws IOException, ClassNotFoundException { reader.readStartTag("default"); GetField g = new GetField(); reader.step(); while (!reader.isEndTag()) { readGetField(g); reader.step(); } reader.assertEndTag("default"); return g; } /** * Method which read a single field from the stream and places it in the * provided GetField object. This method assumes that the XML reader is on a * start tag, and that the item read has a field attribute. * * @param g The GetField object into which the field should be put * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected void readGetField(GetField g) throws IOException, ClassNotFoundException { reader.assertStartTag(); String name = reader.getAttribute("field"); if (name == null) { throw new IOException("Could not read field " + reader.getStartTag() + ", as field attribute was null!"); } if (reader.getStartTag().equals("primitive")) { readPrimitiveGetField(g); } else { g.put(name, readObjectHelper()); } } /** * Method which reads a primitive field from the stream, and places it in the * provided GetField object. This method assumes that the XML parser has just * read a primitive start tag, and that the tag has a field attribute. This * method does consume that end primitive tag. * * @param g The GetField object to put the primitive in * @exception ClassNotFoundException DESCRIBE THE EXCEPTION * @throws IOException If an error occurs */ protected void readPrimitiveGetField(GetField g) throws IOException, ClassNotFoundException { reader.assertStartTag("primitive"); String name = reader.getAttribute("field"); if (name == null) { throw new IOException("Could not read primitive field " + reader.getAttribute("type") + ", as field attribute was null!"); } Class c = getClass(reader.getAttribute("type")); if (c.equals(Integer.TYPE)) { g.put(name, readIntHelper()); } else if (c.equals(Boolean.TYPE)) { g.put(name, readBooleanHelper()); } else if (c.equals(Byte.TYPE)) { g.put(name, readByteHelper()); } else if (c.equals(Character.TYPE)) { g.put(name, readCharHelper()); } else if (c.equals(Double.TYPE)) { g.put(name, readDoubleHelper()); } else if (c.equals(Float.TYPE)) { g.put(name, readFloatHelper()); } else if (c.equals(Long.TYPE)) { g.put(name, readLongHelper()); } else if (c.equals(Short.TYPE)) { g.put(name, readShortHelper()); } else { throw new IllegalArgumentException("Field " + name + " is not primitive!"); } } /** * Method which initiates the default field reading mechanism for the given * object's class. This method reads the start default tag, all of the fields, * and then reads the end default tag. It reads all of the fields using the * readField() method. * * @param o The object which is currently being read in * @param c The class to read the fields for * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected void readFields(Object o, Class c) throws IOException, ClassNotFoundException { reader.readStartTag("default"); reader.step(); while (!reader.isEndTag()) { readField(o, c); reader.step(); } reader.assertEndTag("default"); } /** * Method which reads a single field from the stream, and assignes it to the * provided object. If the field cannot be found in the given class, it is * deserialized and then ignored, in case it is referenced later in the * stream. * * @param o The object which is currently being read in * @param c The class to read the fields for * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected void readField(Object o, Class c) throws IOException, ClassNotFoundException { reader.assertStartTag(); String field = reader.getAttribute("field"); try { Field f = c.getDeclaredField(reader.getAttribute("field")); f.setAccessible(true); int mask = Modifier.STATIC; if ((f.getModifiers() & mask) != 0) { throw new NoSuchFieldException("Field read was static!"); } if (reader.getStartTag().equals("primitive")) { readPrimitiveField(o, f); } else { f.set(o, readObjectHelper()); } } catch (NoSuchFieldException e) { if (reader.getStartTag().equals("primitive")) { reader.readEndTag("primitive"); } else { readObjectHelper(); } } catch (IllegalAccessException e) { // skip IAE, which is very likely caused by setting a final field on < JVM 1.5 } catch (IllegalArgumentException e) { System.err.println("COULD NOT SET FIELD " + field + " OF " + o.getClass().getName() + " - SKIPPING. THIS SHOULD NOT HAPPEN!" + e); e.printStackTrace(); } } /** * Method which reads a primitive field from the stream, and places it in the * given object. This method assumes that the XML parser has just read a * primitive start tag, and that the tag has a field attribute. This method * does consume that end primitive tag. * * @param o The object to put the primitive in * @param f The field representing the primitive about to be read * @exception IllegalAccessException DESCRIBE THE EXCEPTION * @throws IOException If an error occurs */ protected void readPrimitiveField(Object o, Field f) throws IOException, IllegalAccessException { reader.assertStartTag("primitive"); if (f.getType().equals(Integer.TYPE)) { f.setInt(o, readIntHelper()); } else if (f.getType().equals(Boolean.TYPE)) { f.setBoolean(o, readBooleanHelper()); } else if (f.getType().equals(Byte.TYPE)) { f.setByte(o, readByteHelper()); } else if (f.getType().equals(Character.TYPE)) { f.setChar(o, readCharHelper()); } else if (f.getType().equals(Double.TYPE)) { f.setDouble(o, readDoubleHelper()); } else if (f.getType().equals(Float.TYPE)) { f.setFloat(o, readFloatHelper()); } else if (f.getType().equals(Long.TYPE)) { f.setLong(o, readLongHelper()); } else if (f.getType().equals(Short.TYPE)) { f.setInt(o, readShortHelper()); } else { throw new IllegalArgumentException("Field " + f + " is not primitive!"); } } /** * Method which reads an array off of the stream. This method expects that a * start array tag has just been read, and does consume the end array tag. * This method constructs an array of the provided base type, and then * recursively reads in all of the objects for the array. * * @param shared Whether or not to add this array to the references table * @return DESCRIBE THE RETURN VALUE * @throws IOException If an error occurs * @throws ClassNotFoundException If the class cannot be found */ protected Object readArray(boolean shared) throws IOException, ClassNotFoundException { reader.assertStartTag("array"); Class c = getClass(reader.getAttribute("base")); int length = Integer.valueOf(reader.getAttribute("length")).intValue(); int dim = Integer.valueOf(reader.getAttribute("dim")).intValue(); Object result = Array.newInstance(c, length); if (shared && (reader.getAttribute("id") != null)) { putReference(reader.getAttribute("id"), result); } for (int i = 0; i < length; i++) { if (c.equals(Integer.TYPE)) { Array.setInt(result, i, readInt()); } else if (c.equals(Boolean.TYPE)) { Array.setBoolean(result, i, readBoolean()); } else if (c.equals(Byte.TYPE)) { Array.setByte(result, i, readByte()); } else if (c.equals(Character.TYPE)) { Array.setChar(result, i, readChar()); } else if (c.equals(Double.TYPE)) { Array.setDouble(result, i, readDouble()); } else if (c.equals(Float.TYPE)) { Array.setFloat(result, i, readFloat()); } else if (c.equals(Long.TYPE)) { Array.setLong(result, i, readLong()); } else if (c.equals(Short.TYPE)) { Array.setShort(result, i, readShort()); } else { Array.set(result, i, readObject()); } } reader.readEndTag("array"); return result; } // ----- Internal helper methods ----- /** * This method returns the readResolve() method of a given class, if such a * method exists. This method searches the class's heirarchy for a * readResolve() method which is assessible by the given class. If no such * method is found, null is returned. * * @param cl The class to find the readResolve() of * @return The method, or null if none was found */ private static Method getReadResolve(Class cl) { synchronized (READ_RESOLVES) { if (READ_RESOLVES.containsKey(cl)) { return (Method) READ_RESOLVES.get(cl); } Method meth = null; Class defCl = cl; while (defCl != null) { try { meth = defCl.getDeclaredMethod("readResolve", new Class[0]); break; } catch (NoSuchMethodException ex) { defCl = defCl.getSuperclass(); } } if (meth == null) { READ_RESOLVES.put(cl, null); return null; } meth.setAccessible(true); int mods = meth.getModifiers(); if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) { READ_RESOLVES.put(cl, null); return null; } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) { READ_RESOLVES.put(cl, meth); return meth; } else if ((mods & Modifier.PRIVATE) != 0) { if (cl == defCl) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -