home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 1999 April / DPPCPRO0499.ISO / April / Notes / 50b2wic.exe / DATA1.CAB / NotesProgramFilesJavaSupport / rt.jar / java / io / ObjectStreamClass.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-04-23  |  10.0 KB  |  485 lines

  1. package java.io;
  2.  
  3. import java.security.DigestOutputStream;
  4. import java.security.MessageDigest;
  5. import java.security.NoSuchAlgorithmException;
  6. import sun.misc.Ref;
  7.  
  8. public class ObjectStreamClass implements Serializable {
  9.    static final long serialVersionUID = -6120832682080437368L;
  10.    private static final int M_TRANSIENT = 128;
  11.    private static final int M_PRIVATE = 2;
  12.    private static final int M_STATIC = 8;
  13.    private static ObjectStreamClassEntry[] descriptorFor = new ObjectStreamClassEntry[61];
  14.    private String name;
  15.    private ObjectStreamClass superclass;
  16.    private boolean serializable;
  17.    private boolean externalizable;
  18.    private ObjectStreamField[] fields;
  19.    private Class ofClass;
  20.    private long suid;
  21.    private int[] fieldSequence;
  22.    private boolean hasWriteObjectMethod;
  23.    private boolean hasExternalizableBlockData;
  24.    private ObjectStreamClass localClassDesc;
  25.    private static Class classSerializable = null;
  26.    private static Class classExternalizable = null;
  27.  
  28.    public static ObjectStreamClass lookup(Class var0) {
  29.       Object var1 = null;
  30.       ObjectStreamClassEntry[] var3 = descriptorFor;
  31.       synchronized(var3){}
  32.  
  33.       ObjectStreamClass var2;
  34.       try {
  35.          ObjectStreamClass var11 = findDescriptorFor(var0);
  36.          if (var11 == null) {
  37.             boolean var5 = classSerializable.isAssignableFrom(var0);
  38.             if (!var5) {
  39.                var2 = null;
  40.                return var2;
  41.             }
  42.  
  43.             boolean var6 = classExternalizable.isAssignableFrom(var0);
  44.             if (var6) {
  45.                var5 = false;
  46.             }
  47.  
  48.             ObjectStreamClass var7 = null;
  49.             if (var5) {
  50.                Class var8 = var0.getSuperclass();
  51.                if (var8 != null) {
  52.                   var7 = lookup(var8);
  53.                }
  54.             }
  55.  
  56.             var11 = new ObjectStreamClass(var0, var7, var5, var6);
  57.             return var11;
  58.          }
  59.  
  60.          var2 = var11;
  61.       } catch (Throwable var10) {
  62.          throw var10;
  63.       }
  64.  
  65.       return var2;
  66.    }
  67.  
  68.    public String getName() {
  69.       return this.name;
  70.    }
  71.  
  72.    public long getSerialVersionUID() {
  73.       return this.suid;
  74.    }
  75.  
  76.    public Class forClass() {
  77.       return this.ofClass;
  78.    }
  79.  
  80.    public String toString() {
  81.       StringBuffer var1 = new StringBuffer();
  82.       var1.append(this.name);
  83.       var1.append(": static final long serialVersionUID = ");
  84.       var1.append(Long.toString(this.suid));
  85.       var1.append("L;");
  86.       return var1.toString();
  87.    }
  88.  
  89.    private ObjectStreamClass(Class var1, ObjectStreamClass var2, boolean var3, boolean var4) {
  90.       this.ofClass = var1;
  91.       this.name = var1.getName();
  92.       this.superclass = var2;
  93.       this.serializable = var3;
  94.       this.externalizable = var4;
  95.       insertDescriptorFor(this);
  96.       if (!this.externalizable && !this.name.equals("java.lang.String")) {
  97.          this.fields = this.getFields0(var1);
  98.          if (this.fields.length > 0) {
  99.             boolean var6;
  100.             do {
  101.                var6 = true;
  102.  
  103.                for(int var5 = this.fields.length - 1; var5 > 0; --var5) {
  104.                   if (this.fields[var5 - 1].compare(this.fields[var5]) > 0) {
  105.                      ObjectStreamField var7 = this.fields[var5];
  106.                      this.fields[var5] = this.fields[var5 - 1];
  107.                      this.fields[var5 - 1] = var7;
  108.                      var6 = false;
  109.                   }
  110.                }
  111.             } while(!var6);
  112.  
  113.             this.computeFieldSequence();
  114.          }
  115.       } else {
  116.          this.fields = new ObjectStreamField[0];
  117.       }
  118.  
  119.       this.suid = getSerialVersionUID(var1);
  120.       if (this.suid == 0L) {
  121.          this.suid = computeSerialVersionUID(var1);
  122.       }
  123.  
  124.       this.hasWriteObjectMethod = hasWriteObject(var1);
  125.    }
  126.  
  127.    ObjectStreamClass(String var1, long var2) {
  128.       this.name = var1;
  129.       this.suid = var2;
  130.       this.superclass = null;
  131.    }
  132.  
  133.    void setClass(Class var1) throws InvalidClassException {
  134.       if (var1 == null) {
  135.          this.localClassDesc = null;
  136.          this.ofClass = null;
  137.  
  138.          for(int var7 = 0; var7 < this.fields.length; ++var7) {
  139.             this.fields[var7].offset = -1;
  140.          }
  141.  
  142.          this.computeFieldSequence();
  143.       } else {
  144.          this.localClassDesc = lookup(var1);
  145.          if (this.localClassDesc == null) {
  146.             throw new InvalidClassException(var1.getName(), "Local class not compatible");
  147.          } else if (this.suid == this.localClassDesc.suid || var1.isArray() && !var1.getName().equals(this.name)) {
  148.             if (!compareClassNames(this.name, var1.getName(), '.')) {
  149.                throw new InvalidClassException(this.name, "Incompatible local class name: " + var1.getName());
  150.             } else if (this.serializable == this.localClassDesc.serializable && this.externalizable == this.localClassDesc.externalizable) {
  151.                ObjectStreamField[] var2 = this.localClassDesc.getFields();
  152.                ObjectStreamField[] var3 = this.fields;
  153.                int var4 = 0;
  154.  
  155.                label54:
  156.                for(int var5 = 0; var5 < var3.length; ++var5) {
  157.                   for(int var6 = var4; var6 < var2.length; ++var6) {
  158.                      if (var3[var5].name.equals(var2[var6].name)) {
  159.                         if (!var3[var5].typeEquals(var2[var6])) {
  160.                            throw new InvalidClassException(var1.getName(), "The type of field " + var3[var5].name + " of class " + this.name + " is incompatible.");
  161.                         }
  162.  
  163.                         var4 = var6;
  164.                         var3[var5].offset = var2[var6].offset;
  165.                         continue label54;
  166.                      }
  167.                   }
  168.  
  169.                   var3[var5].offset = -1;
  170.                }
  171.  
  172.                this.computeFieldSequence();
  173.                this.ofClass = var1;
  174.             } else {
  175.                throw new InvalidClassException(var1.getName(), "Serialization incompatible with Externalization");
  176.             }
  177.          } else {
  178.             throw new InvalidClassException(var1.getName(), "Local class not compatible: stream classdesc serialVersionUID=" + this.suid + " local class serialVersionUID=" + this.localClassDesc.suid);
  179.          }
  180.       }
  181.    }
  182.  
  183.    static boolean compareClassNames(String var0, String var1, char var2) {
  184.       int var3 = var0.lastIndexOf(var2);
  185.       if (var3 < 0) {
  186.          var3 = 0;
  187.       }
  188.  
  189.       int var4 = var1.lastIndexOf(var2);
  190.       if (var4 < 0) {
  191.          var4 = 0;
  192.       }
  193.  
  194.       boolean var5 = var0.regionMatches(false, var3, var1, var4, var0.length() - var3);
  195.       return var5;
  196.    }
  197.  
  198.    boolean typeEquals(ObjectStreamClass var1) {
  199.       return this.suid == var1.suid && compareClassNames(this.name, var1.name, '.');
  200.    }
  201.  
  202.    ObjectStreamField[] getFields() {
  203.       return this.fields;
  204.    }
  205.  
  206.    void setSuperclass(ObjectStreamClass var1) {
  207.       this.superclass = var1;
  208.    }
  209.  
  210.    ObjectStreamClass getSuperclass() {
  211.       return this.superclass;
  212.    }
  213.  
  214.    boolean hasWriteObject() {
  215.       return this.hasWriteObjectMethod;
  216.    }
  217.  
  218.    boolean hasExternalizableBlockDataMode() {
  219.       return this.hasExternalizableBlockData;
  220.    }
  221.  
  222.    ObjectStreamClass localClassDescriptor() {
  223.       return this.localClassDesc;
  224.    }
  225.  
  226.    boolean isExternalizable() {
  227.       return this.externalizable;
  228.    }
  229.  
  230.    int[] getFieldSequence() {
  231.       return this.fieldSequence;
  232.    }
  233.  
  234.    private void computeFieldSequence() {
  235.       this.fieldSequence = new int[this.fields.length * 2];
  236.  
  237.       for(int var1 = 0; var1 < this.fields.length; ++var1) {
  238.          this.fieldSequence[var1 * 2] = this.fields[var1].type;
  239.          this.fieldSequence[var1 * 2 + 1] = this.fields[var1].offset;
  240.       }
  241.  
  242.    }
  243.  
  244.    private static long computeSerialVersionUID(Class var0) {
  245.       ByteArrayOutputStream var1 = new ByteArrayOutputStream(512);
  246.       long var2 = 0L;
  247.  
  248.       try {
  249.          MessageDigest var4 = MessageDigest.getInstance("SHA");
  250.          DigestOutputStream var5 = new DigestOutputStream(var1, var4);
  251.          DataOutputStream var6 = new DataOutputStream(var5);
  252.          var6.writeUTF(var0.getName());
  253.          int var7 = getClassAccess(var0);
  254.          var7 &= 1553;
  255.          var6.writeInt(var7);
  256.          Class[] var8 = var0.getInterfaces();
  257.          quicksort(var8);
  258.  
  259.          for(int var9 = 0; var9 < var8.length; ++var9) {
  260.             var6.writeUTF(var8[var9].getName());
  261.          }
  262.  
  263.          String[] var10 = getFieldSignatures(var0);
  264.          quicksort(var10);
  265.  
  266.          for(int var11 = 0; var11 < var10.length; ++var11) {
  267.             String var12 = var10[var11];
  268.             int var13 = getFieldAccess(var0, var12);
  269.             if ((var13 & 2) != 2 || (var13 & 128) != 128 && (var13 & 8) != 8) {
  270.                int var14 = var12.indexOf(32);
  271.                String var15 = var12.substring(0, var14);
  272.                String var16 = var12.substring(var14 + 1);
  273.                var6.writeUTF(var15);
  274.                var6.writeInt(var13);
  275.                var6.writeUTF(var16);
  276.             }
  277.          }
  278.  
  279.          String[] var22 = getMethodSignatures(var0);
  280.          quicksort(var22);
  281.  
  282.          for(int var23 = 0; var23 < var22.length; ++var23) {
  283.             String var24 = var22[var23];
  284.             int var26 = getMethodAccess(var0, var24);
  285.             if ((var26 & 2) == 0) {
  286.                int var28 = var24.indexOf(32);
  287.                String var17 = var24.substring(0, var28);
  288.                String var18 = var24.substring(var28 + 1);
  289.                var18 = var18.replace('/', '.');
  290.                var6.writeUTF(var17);
  291.                var6.writeInt(var26);
  292.                var6.writeUTF(var18);
  293.             }
  294.          }
  295.  
  296.          byte[] var25 = var4.digest();
  297.  
  298.          for(int var27 = 0; var27 < Math.min(8, var25.length); ++var27) {
  299.             var2 += (long)(var25[var27] & 255) << var27 * 8;
  300.          }
  301.       } catch (IOException var19) {
  302.          var2 = -1L;
  303.       } catch (NoSuchAlgorithmException var20) {
  304.          throw new SecurityException(((Throwable)var20).getMessage());
  305.       }
  306.  
  307.       return var2;
  308.    }
  309.  
  310.    private static native int getClassAccess(Class var0);
  311.  
  312.    private static native String[] getMethodSignatures(Class var0);
  313.  
  314.    private static native int getMethodAccess(Class var0, String var1);
  315.  
  316.    private static native String[] getFieldSignatures(Class var0);
  317.  
  318.    private static native int getFieldAccess(Class var0, String var1);
  319.  
  320.    void write(ObjectOutputStream var1) throws IOException {
  321.       int var2 = 0;
  322.       if (this.hasWriteObjectMethod) {
  323.          var2 |= 1;
  324.       }
  325.  
  326.       if (this.serializable) {
  327.          var2 |= 2;
  328.       }
  329.  
  330.       if (this.externalizable) {
  331.          var2 |= 4;
  332.       }
  333.  
  334.       var1.writeByte(var2);
  335.       var1.writeShort(this.fields.length);
  336.       boolean var3 = var1.enableReplace;
  337.       var1.enableReplace = false;
  338.  
  339.       try {
  340.          for(int var6 = 0; var6 < this.fields.length; ++var6) {
  341.             ObjectStreamField var7 = this.fields[var6];
  342.             var1.writeByte(var7.type);
  343.             var1.writeUTF(var7.name);
  344.             if (!var7.isPrimitive()) {
  345.                var1.writeObject(var7.typeString);
  346.             }
  347.          }
  348.       } finally {
  349.          var1.enableReplace = var3;
  350.       }
  351.  
  352.    }
  353.  
  354.    void read(ObjectInputStream var1) throws IOException, ClassNotFoundException {
  355.       byte var2 = var1.readByte();
  356.       this.serializable = (var2 & 2) != 0;
  357.       this.externalizable = (var2 & 4) != 0;
  358.       this.hasWriteObjectMethod = this.serializable ? (var2 & 1) != 0 : false;
  359.       byte var3 = 1;
  360.       this.hasExternalizableBlockData = this.externalizable ? (var2 & var3) != 0 : false;
  361.       short var4 = var1.readShort();
  362.       this.fields = new ObjectStreamField[var4];
  363.       boolean var5 = var1.enableResolve;
  364.       var1.enableResolve = false;
  365.  
  366.       try {
  367.          for(int var8 = 0; var8 < var4; ++var8) {
  368.             char var9 = (char)var1.readByte();
  369.             String var10 = var1.readUTF();
  370.             String var11 = null;
  371.             if (var9 == '[' || var9 == 'L') {
  372.                var11 = (String)var1.readObject();
  373.             }
  374.  
  375.             this.fields[var8] = new ObjectStreamField(var10, var9, -1, var11);
  376.          }
  377.       } finally {
  378.          var1.enableResolve = var5;
  379.       }
  380.  
  381.    }
  382.  
  383.    private static ObjectStreamClass findDescriptorFor(Class var0) {
  384.       int var1 = var0.hashCode();
  385.  
  386.       ObjectStreamClassEntry var3;
  387.       for(int var2 = (var1 & Integer.MAX_VALUE) % descriptorFor.length; (var3 = descriptorFor[var2]) != null && ((Ref)var3).check() == null; descriptorFor[var2] = var3.next) {
  388.       }
  389.  
  390.       for(ObjectStreamClassEntry var4 = var3; var3 != null; var3 = var3.next) {
  391.          ObjectStreamClass var5 = (ObjectStreamClass)((Ref)var3).check();
  392.          if (var5 == null) {
  393.             var4.next = var3.next;
  394.          } else {
  395.             if (var5.ofClass == var0) {
  396.                return var5;
  397.             }
  398.  
  399.             var4 = var3;
  400.          }
  401.       }
  402.  
  403.       return null;
  404.    }
  405.  
  406.    private static void insertDescriptorFor(ObjectStreamClass var0) {
  407.       if (findDescriptorFor(var0.ofClass) == null) {
  408.          int var1 = var0.ofClass.hashCode();
  409.          int var2 = (var1 & Integer.MAX_VALUE) % descriptorFor.length;
  410.          ObjectStreamClassEntry var3 = new ObjectStreamClassEntry();
  411.          ((Ref)var3).setThing(var0);
  412.          var3.next = descriptorFor[var2];
  413.          descriptorFor[var2] = var3;
  414.       }
  415.    }
  416.  
  417.    private native ObjectStreamField[] getFields0(Class var1);
  418.  
  419.    private static native long getSerialVersionUID(Class var0);
  420.  
  421.    private static native boolean hasWriteObject(Class var0);
  422.  
  423.    private static int doCompare(Object var0, Object var1) {
  424.       String var2;
  425.       String var3;
  426.       if (var0 instanceof String && var1 instanceof String) {
  427.          var2 = (String)var0;
  428.          var3 = (String)var1;
  429.       } else if (var0 instanceof Class && var1 instanceof Class) {
  430.          Class var6 = (Class)var0;
  431.          Class var7 = (Class)var1;
  432.          var2 = var6.getName();
  433.          var3 = var7.getName();
  434.       } else {
  435.          if (!(var0 instanceof ObjectStreamField) || !(var1 instanceof ObjectStreamField)) {
  436.             throw new Error("Unsupported types");
  437.          }
  438.  
  439.          ObjectStreamField var4 = (ObjectStreamField)var0;
  440.          ObjectStreamField var5 = (ObjectStreamField)var1;
  441.          var2 = var4.name;
  442.          var3 = var5.name;
  443.       }
  444.  
  445.       return var2.compareTo(var3);
  446.    }
  447.  
  448.    private static void swap(Object[] var0, int var1, int var2) {
  449.       Object var3 = var0[var1];
  450.       var0[var1] = var0[var2];
  451.       var0[var2] = var3;
  452.    }
  453.  
  454.    private static void quicksort(Object[] var0, int var1, int var2) {
  455.       if (var1 < var2) {
  456.          swap(var0, var1, (var1 + var2) / 2);
  457.          int var4 = var1;
  458.  
  459.          for(int var3 = var1 + 1; var3 <= var2; ++var3) {
  460.             if (doCompare(var0[var3], var0[var1]) < 0) {
  461.                ++var4;
  462.                swap(var0, var4, var3);
  463.             }
  464.          }
  465.  
  466.          swap(var0, var1, var4);
  467.          quicksort(var0, var1, var4 - 1);
  468.          quicksort(var0, var4 + 1, var2);
  469.       }
  470.    }
  471.  
  472.    private static void quicksort(Object[] var0) {
  473.       quicksort(var0, 0, var0.length - 1);
  474.    }
  475.  
  476.    static {
  477.       try {
  478.          classSerializable = Class.forName("java.io.Serializable");
  479.          classExternalizable = Class.forName("java.io.Externalizable");
  480.       } catch (Throwable var0) {
  481.          System.err.println("Could not load java.io.Serializable or java.io.Externalizable.");
  482.       }
  483.    }
  484. }
  485.