⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlobjectoutputstream.java

📁 pastry的java实现的2.0b版
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************"FreePastry" Peer-to-Peer Application Development Substrate Copyright 2002, Rice University. All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions aremet:- Redistributions of source code must retain the above copyrightnotice, this list of conditions and the following disclaimer.- Redistributions in binary form must reproduce the above copyrightnotice, this list of conditions and the following disclaimer in thedocumentation and/or other materials provided with the distribution.- Neither  the name  of Rice  University (RICE) nor  the names  of itscontributors may be  used to endorse or promote  products derived fromthis software without specific prior written permission.This software is provided by RICE and the contributors on an "as is"basis, without any representations or warranties of any kind, expressor implied including, but not limited to, representations orwarranties of non-infringement, merchantability or fitness for aparticular purpose. In no event shall RICE or contributors be liablefor any direct, indirect, incidental, special, exemplary, orconsequential damages (including, but not limited to, procurement ofsubstitute goods or services; loss of use, data, or profits; orbusiness interruption) however caused and on any theory of liability,whether in contract, strict liability, or tort (including negligenceor otherwise) arising in any way out of the use of this software, evenif advised of the possibility of such damage.********************************************************************************/package rice.p2p.util;import java.io.*;import java.lang.reflect.*;import java.util.*;/** * XMLObjectOutputStream is an extension of ObjectOutputStream which provides * for serialization for arbitrary Java objects, in the same manner as the * ObjectOutputStream class. This class supports all of the features of the * ObjectOutputStream, including serialization support for any Java object graph * implementing the Serializable interface, maintenance of references in the * object graph, support for Externalizable classes, custom serialization via * the writeObject() method, alternate field writing mechanisms via the * putFields() and writeFields() methods, support for the writeUnshared() * method, custom serializable field specification via the * serialPersistentFields field, and dynamic object replacement via the * writeReplace() method. The format of the XML data written does conform to the * JSX XML Schema, available online at http://www.jsx.org/jsx.xsd. This class is * designed to be able to write objects which can then be deserialized using * JSX, however, this has not been fully tested and bugs may be encountered. * * @version $Id: XMLObjectOutputStream.java 3142 2006-03-15 16:11:33Z jstewart $ * @author Alan Mislove */public class XMLObjectOutputStream extends ObjectOutputStream {  /**   * The underlying XML writing engine   */  protected XMLWriter writer;  /**   * The collection of references stored in the stream so far, maps   * Integer(hash) -> reference name.   */  protected Hashtable references;  /**   * A counter used to generate unique references   */  protected int next = 0;  /**   * The stack of objects which are currently being written to the stream   */  protected Stack currentObjects;  /**   * The stack of classes which are currently being written to the stream   */  protected Stack currentClasses;  /**   * The stack of putFields which are currently being written to the stream   */  protected Stack currentPutFields;  private String debugstr;  /**   * A cache of the writeReplace() methods, mapping class->writeReplace()   */  protected static SoftHashMap WRITE_REPLACES = new SoftHashMap();  /**   * A cache of the writeObject() methods, mapping class->writeObject()   */  protected static SoftHashMap WRITE_OBJECTS = new SoftHashMap();  /**   * A cache of the persistentFields, mapping class->Field[]   */  protected static SoftHashMap PERSISTENT_FIELDS = new SoftHashMap();  /**   * Constructor which writes data from the given output stream in order   * serialize objects. This constructor also writes the header to the stream,   * and throws an IOException if an error occurs while writing the header.   *   * @param out The output stream to write data to   * @exception IOException DESCRIBE THE EXCEPTION   * @throws IOException If the an error occurs   */  public XMLObjectOutputStream(OutputStream out) throws IOException {    super();    try {      this.writer = new XMLWriter(out);      int hash = 0;      if (writer != null) {        hash = writer.hashCode();      }      this.debugstr = "writer after new, in try: " + writer + " " + hash + "\n";    } catch (NoClassDefFoundError ncdfe) {      System.err.println("ERROR: Make sure to add xmlpull.jar to the classpath");      throw ncdfe;    }    int hash = 0;    if (writer != null) {      hash = writer.hashCode();    }    this.debugstr += "writer after try: " + writer + " " + hash + "\n";    this.references = new Hashtable();    this.currentObjects = new Stack();    this.currentClasses = new Stack();    this.currentPutFields = new Stack();    hash = 0;    if (writer != null) {      hash = writer.hashCode();    }    this.debugstr += "writer before writeStreamHeader: " + writer + " " + hash + "\n";    writeStreamHeader();  }  // ----- Internal Helper Methods -----  /**   * This method returns the writeReplce() method of a given class, if such a   * method exists. This method searches the class's heirarchy for a   * writeReplace() method which is assessible by the given class. If no such   * method is found, null is returned.   *   * @param cl The class to find the writeReplace() of   * @return The method, or null if none was found   */  private Method getWriteReplace(Class cl) {    if (WRITE_REPLACES.containsKey(cl)) {      return (Method) WRITE_REPLACES.get(cl);    }    Method meth = null;    Class defCl = cl;    while (defCl != null) {      try {        meth = defCl.getDeclaredMethod("writeReplace", new Class[0]);        break;      } catch (NoSuchMethodException ex) {        defCl = defCl.getSuperclass();      }    }    if (meth == null) {      WRITE_REPLACES.put(cl, meth);      return null;    }    meth.setAccessible(true);    int mods = meth.getModifiers();    if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {    } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) {      WRITE_REPLACES.put(cl, meth);      return meth;    } else if ((mods & Modifier.PRIVATE) != 0) {      if (cl == defCl) {        WRITE_REPLACES.put(cl, meth);        return meth;      }    } else {      WRITE_REPLACES.put(cl, meth);      return meth;    }    WRITE_REPLACES.put(cl, null);    return null;  }  /**   * Method which returns the serializable fields of the provided class. If the   * class has a serialPersistentFields field, then that is used to determine   * which fields are serializable. Otherwise, all declared non-static and   * non-transient fields are returned.   *   * @param cl DESCRIBE THE PARAMETER   * @return The PersistentFields value   */  protected Field[] getPersistentFields(Class cl) {    synchronized (PERSISTENT_FIELDS) {      if (PERSISTENT_FIELDS.containsKey(cl)) {        return (Field[]) PERSISTENT_FIELDS.get(cl);      }      Field[] fields = getSerialPersistentFields(cl);      if (fields == null) {        fields = cl.getDeclaredFields();      }      PERSISTENT_FIELDS.put(cl, fields);      return fields;    }  }  /**   * Method which returns the serializablePersistenFields field of the provided   * class. If no such field exists, then null is returned.   *   * @param c The class to return the fields for   * @return The SerialPersistentFields value   */  protected Field[] getSerialPersistentFields(Class c) {    try {      Field f = c.getDeclaredField("serialPersistentFields");      int mask = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;      if ((f.getModifiers() & mask) != mask) {        return null;      }      f.setAccessible(true);      ObjectStreamField[] serialPersistentFields = (ObjectStreamField[]) f.get(null);      Field[] fields = new Field[serialPersistentFields.length];      for (int i = 0; i < serialPersistentFields.length; i++) {        ObjectStreamField spf = serialPersistentFields[i];        Field thisf = c.getDeclaredField(spf.getName());        if (!((thisf.getType() == spf.getType()) && ((thisf.getModifiers() & Modifier.STATIC) == 0))) {          return null;        }        fields[i] = thisf;      }      return fields;    } catch (NoSuchFieldException ex) {      return null;    } catch (IllegalAccessException e) {      return null;    }  }  /**   * Method which returns the component type of the given array class. If the   * class is not of type array, the class itself is returned   *   * @param array DESCRIBE THE PARAMETER   * @return The component type of the array, or the class itself if not an   *      array   */  protected Class getComponentType(Class array) {    if (array.isArray()) {      return getComponentType(array.getComponentType());    }    return array;  }  /**   * Method which returns the dimension of the given array class. This is   * determines recursively by using the getCompoenetType() method on the class.   *   * @param array DESCRIBE THE PARAMETER   * @return The dimension of the corresponding array class   */  protected int getDimension(Class array) {    if (array.isArray()) {      return 1 + getDimension(array.getComponentType());    }    return 0;  }  /**   * Method which returns an array of classes representing the class hierarchy   * of the provided class, exempting the Object class.   *   * @param c The class to return the heirarchy for   * @return The heierarchy of the provided class   */  protected Class[] getSuperClasses(Class c) {    Vector v = new Vector();    while (true) {      if (c.getSuperclass().equals((new Object()).getClass())) {        break;      }      c = c.getSuperclass();      v.addElement(c);    }    return (Class[]) v.toArray(new Class[0]);  }  /**   * Method which returns a previously stored reference. If the reference cannot   * be found, null is returned.   *   * @param o The object to look up   * @return The reference name, or null if none is found   */  protected String getReference(Object o) {    return (String) references.get(new Reference(o));  }  // ----- ObjectOutputStream Overriding Methods -----  /**   * Method which writes the XML header to the stream. Usually, this is the   * <?xml version="1.0"?> tag, but it may include processing instructions.   *   * @throws IOException If an error occurs   */  protected void writeStreamHeader() throws IOException {    if (writer == null) {      System.out.println("FLUGLE writer is null in writeStreamHeader()...");      System.out.println(debugstr);    }    try {      writer.writeHeader();      writer.start("jsx");      writer.attribute("major", 1);      writer.attribute("minor", 1);      writer.attribute("format", "JSX.DataReader");    } catch (NullPointerException npe) {      System.out.println("FLUGLE writer NPE'd in writeStreamHeader()...");      int hash = 0;      if (writer != null) {        hash = writer.hashCode();      }      this.debugstr += "writer in NPE handler: " + writer + " " + hash + "\n";      System.out.println(debugstr);      throw npe;    }  }  /**   * Method which flushes all buffered data to the output stream.   *   * @throws IOException if an error occurs   */  public void flush() throws IOException {    writer.flush();  }  /**   * Method which closes the underlying output stream for writing. Any   * subsequent writes will throw an IOException.   *   * @exception IOException DESCRIBE THE EXCEPTION   */  public void close() throws IOException {    writer.end("jsx");    writer.close();  }  /**   * Method which resets the output stream, which removes the binding of all   * previously stored references. If the same object is written before and   * after a reset(), it will be written twice to the stream.   *   * @throws IOException If an error occurs, or an object is currently being   *      written   */  public void reset() throws IOException {    if (currentObjects.peek() == null) {      references = new Hashtable();      writeReset();    } else {      throw new IOException("Reset called during active write!");    }  }  /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -