src/share/classes/com/sun/tools/javadoc/SerializedForm.java

Thu, 02 Oct 2008 19:58:40 -0700

author
xdono
date
Thu, 02 Oct 2008 19:58:40 -0700
changeset 117
24a47c3062fe
parent 113
eff38cc97183
child 554
9d9f26857129
permissions
-rw-r--r--

6754988: Update copyright year
Summary: Update for files that have been modified starting July 2008
Reviewed-by: ohair, tbell

     1 /*
     2  * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javadoc;
    28 import com.sun.javadoc.*;
    30 import com.sun.tools.javac.code.Flags;
    31 import com.sun.tools.javac.code.Kinds;
    32 import com.sun.tools.javac.code.Scope;
    33 import com.sun.tools.javac.code.Symbol.VarSymbol;
    34 import com.sun.tools.javac.code.Symbol.ClassSymbol;
    35 import com.sun.tools.javac.code.Symbol.MethodSymbol;
    36 import com.sun.tools.javac.util.Name;
    37 import com.sun.tools.javac.util.ListBuffer;
    38 import com.sun.tools.javac.util.Names;
    40 /**
    41  * The serialized form is the specification of a class' serialization
    42  * state. <p>
    43  *
    44  * It consists of the following information:<p>
    45  *
    46  * <pre>
    47  * 1. Whether class is Serializable or Externalizable.
    48  * 2. Javadoc for serialization methods.
    49  *    a. For Serializable, the optional readObject, writeObject,
    50  *       readResolve and writeReplace.
    51  *       serialData tag describes, in prose, the sequence and type
    52  *       of optional data written by writeObject.
    53  *    b. For Externalizable, writeExternal and readExternal.
    54  *       serialData tag describes, in prose, the sequence and type
    55  *       of optional data written by writeExternal.
    56  * 3. Javadoc for serialization data layout.
    57  *    a. For Serializable, the name,type and description
    58  *       of each Serializable fields.
    59  *    b. For Externalizable, data layout is described by 2(b).
    60  * </pre>
    61  *
    62  * @since 1.2
    63  * @author Joe Fialli
    64  * @author Neal Gafter (rewrite but not too proud)
    65  */
    66 class SerializedForm {
    67     ListBuffer<MethodDoc> methods = new ListBuffer<MethodDoc>();
    69     /* List of FieldDocImpl - Serializable fields.
    70      * Singleton list if class defines Serializable fields explicitly.
    71      * Otherwise, list of default serializable fields.
    72      * 0 length list for Externalizable.
    73      */
    74     private final ListBuffer<FieldDocImpl> fields = new ListBuffer<FieldDocImpl>();
    76     /* True if class specifies serializable fields explicitly.
    77      * using special static member, serialPersistentFields.
    78      */
    79     private boolean definesSerializableFields = false;
    81     // Specially treated field/method names defined by Serialization.
    82     private static final String SERIALIZABLE_FIELDS = "serialPersistentFields";
    83     private static final String READOBJECT  = "readObject";
    84     private static final String WRITEOBJECT = "writeObject";
    85     private static final String READRESOLVE  = "readResolve";
    86     private static final String WRITEREPLACE = "writeReplace";
    87     private static final String READOBJECTNODATA = "readObjectNoData";
    89     /**
    90      * Constructor.
    91      *
    92      * Catalog Serializable fields for Serializable class.
    93      * Catalog serialization methods for Serializable and
    94      * Externalizable classes.
    95      */
    96     SerializedForm(DocEnv env, ClassSymbol def, ClassDocImpl cd) {
    97         if (cd.isExternalizable()) {
    98             /* look up required public accessible methods,
    99              *   writeExternal and readExternal.
   100              */
   101             String[] readExternalParamArr = { "java.io.ObjectInput" };
   102             String[] writeExternalParamArr = { "java.io.ObjectOutput" };
   103             MethodDoc md = cd.findMethod("readExternal", readExternalParamArr);
   104             if (md != null) {
   105                 methods.append(md);
   106             }
   107             md = cd.findMethod("writeExternal", writeExternalParamArr);
   108             if (md != null) {
   109                 methods.append(md);
   110                 Tag tag[] = md.tags("serialData");
   111             }
   112         // } else { // isSerializable() //### ???
   113         } else if (cd.isSerializable()) {
   115             VarSymbol dsf = getDefinedSerializableFields(def);
   116             if (dsf != null) {
   118                 /* Define serializable fields with array of ObjectStreamField.
   119                  * Each ObjectStreamField should be documented by a
   120                  * serialField tag.
   121                  */
   122                 definesSerializableFields = true;
   123                 //### No modifier filtering applied here.
   124                 FieldDocImpl dsfDoc = env.getFieldDoc(dsf);
   125                 fields.append(dsfDoc);
   126                 mapSerialFieldTagImplsToFieldDocImpls(dsfDoc, env, def);
   127             } else {
   129                 /* Calculate default Serializable fields as all
   130                  * non-transient, non-static fields.
   131                  * Fields should be documented by serial tag.
   132                  */
   133                 computeDefaultSerializableFields(env, def, cd);
   134             }
   136            /* Check for optional customized readObject, writeObject,
   137             * readResolve and writeReplace, which can all contain
   138             * the serialData tag.        */
   139             addMethodIfExist(env, def, READOBJECT);
   140             addMethodIfExist(env, def, WRITEOBJECT);
   141             addMethodIfExist(env, def, READRESOLVE);
   142             addMethodIfExist(env, def, WRITEREPLACE);
   143             addMethodIfExist(env, def, READOBJECTNODATA);
   144         }
   145     }
   147     /*
   148      * Check for explicit Serializable fields.
   149      * Check for a private static array of ObjectStreamField with
   150      * name SERIALIZABLE_FIELDS.
   151      */
   152     private VarSymbol getDefinedSerializableFields(ClassSymbol def) {
   153         Names names = def.name.table.names;
   155         /* SERIALIZABLE_FIELDS can be private,
   156          * so must lookup by ClassSymbol, not by ClassDocImpl.
   157          */
   158         for (Scope.Entry e = def.members().lookup(names.fromString(SERIALIZABLE_FIELDS)); e.scope != null; e = e.next()) {
   159             if (e.sym.kind == Kinds.VAR) {
   160                 VarSymbol f = (VarSymbol)e.sym;
   161                 if ((f.flags() & Flags.STATIC) != 0 &&
   162                     (f.flags() & Flags.PRIVATE) != 0) {
   163                     return f;
   164                 }
   165             }
   166         }
   167         return null;
   168     }
   170     /*
   171      * Compute default Serializable fields from all members of ClassSymbol.
   172      *
   173      * Since the fields of ClassDocImpl might not contain private or
   174      * package accessible fields, must walk over all members of ClassSymbol.
   175      */
   176     private void computeDefaultSerializableFields(DocEnv env,
   177                                                   ClassSymbol def,
   178                                                   ClassDocImpl cd) {
   179         for (Scope.Entry e = def.members().elems; e != null; e = e.sibling) {
   180             if (e.sym != null && e.sym.kind == Kinds.VAR) {
   181                 VarSymbol f = (VarSymbol)e.sym;
   182                 if ((f.flags() & Flags.STATIC) == 0 &&
   183                     (f.flags() & Flags.TRANSIENT) == 0) {
   184                     //### No modifier filtering applied here.
   185                     FieldDocImpl fd = env.getFieldDoc(f);
   186                     //### Add to beginning.
   187                     //### Preserve order used by old 'javadoc'.
   188                     fields.prepend(fd);
   189                 }
   190             }
   191         }
   192     }
   194     /*
   195      * Catalog Serializable method if it exists in current ClassSymbol.
   196      * Do not look for method in superclasses.
   197      *
   198      * Serialization requires these methods to be non-static.
   199      *
   200      * @param method should be an unqualified Serializable method
   201      *               name either READOBJECT, WRITEOBJECT, READRESOLVE
   202      *               or WRITEREPLACE.
   203      * @param visibility the visibility flag for the given method.
   204      */
   205     private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) {
   206         Names names = def.name.table.names;
   208         for (Scope.Entry e = def.members().lookup(names.fromString(methodName)); e.scope != null; e = e.next()) {
   209             if (e.sym.kind == Kinds.MTH) {
   210                 MethodSymbol md = (MethodSymbol)e.sym;
   211                 if ((md.flags() & Flags.STATIC) == 0) {
   212                     /*
   213                      * WARNING: not robust if unqualifiedMethodName is overloaded
   214                      *          method. Signature checking could make more robust.
   215                      * READOBJECT takes a single parameter, java.io.ObjectInputStream.
   216                      * WRITEOBJECT takes a single parameter, java.io.ObjectOutputStream.
   217                      */
   218                     methods.append(env.getMethodDoc(md));
   219                 }
   220             }
   221         }
   222     }
   224     /*
   225      * Associate serialField tag fieldName with FieldDocImpl member.
   226      * Note: A serialField tag does not have to map an existing field
   227      *       of a class.
   228      */
   229     private void mapSerialFieldTagImplsToFieldDocImpls(FieldDocImpl spfDoc,
   230                                                        DocEnv env,
   231                                                        ClassSymbol def) {
   232         Names names = def.name.table.names;
   234         SerialFieldTag[] sfTag = spfDoc.serialFieldTags();
   235         for (int i = 0; i < sfTag.length; i++) {
   236             Name fieldName = names.fromString(sfTag[i].fieldName());
   238             // Look for a FieldDocImpl that is documented by serialFieldTagImpl.
   239             for (Scope.Entry e = def.members().lookup(fieldName); e.scope != null; e = e.next()) {
   240                 if (e.sym.kind == Kinds.VAR) {
   241                     VarSymbol f = (VarSymbol)e.sym;
   242                     FieldDocImpl fdi = env.getFieldDoc(f);
   243                     ((SerialFieldTagImpl)(sfTag[i])).mapToFieldDocImpl(fdi);
   244                     break;
   245                 }
   246             }
   247         }
   248     }
   250     /**
   251      * Return serializable fields in class. <p>
   252      *
   253      * Returns either a list of default fields documented by serial tag comment or
   254      *         javadoc comment<p>
   255      * Or Returns a single FieldDocImpl for serialPersistentField. There is a
   256      *         serialField tag for each serializable field.<p>
   257      *
   258      * @return an array of FieldDocImpl for representing the visible
   259      *         fields in this class.
   260      */
   261     FieldDoc[] fields() {
   262         return (FieldDoc[])fields.toArray(new FieldDocImpl[fields.length()]);
   263     }
   265     /**
   266      * Return serialization methods in class.
   267      *
   268      * @return an array of MethodDocImpl for serialization methods in this class.
   269      */
   270     MethodDoc[] methods() {
   271         return methods.toArray(new MethodDoc[methods.length()]);
   272     }
   274     /**
   275      * Returns true if Serializable fields are defined explicitly using
   276      * member, serialPersistentFields.
   277      *
   278      * @see #fields()
   279      */
   280     boolean definesSerializableFields() {
   281         return definesSerializableFields;
   282     }
   283 }

mercurial