All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.tools.oldlets.javadoc.main.SerializedForm Maven / Gradle / Ivy

There is a newer version: 1.0
Show newest version
/*
 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.oldlets.javadoc.main;

import com.sun.javadoc.SerialFieldTag;
import com.sun.javadoc.Tag;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.util.*;

/**
 * The serialized form is the specification of a class' serialization
 * state. 

* * It consists of the following information:

* *

 * 1. Whether class is Serializable or Externalizable.
 * 2. Javadoc for serialization methods.
 *    a. For Serializable, the optional readObject, writeObject,
 *       readResolve and writeReplace.
 *       serialData tag describes, in prose, the sequence and type
 *       of optional data written by writeObject.
 *    b. For Externalizable, writeExternal and readExternal.
 *       serialData tag describes, in prose, the sequence and type
 *       of optional data written by writeExternal.
 * 3. Javadoc for serialization data layout.
 *    a. For Serializable, the name,type and description
 *       of each Serializable fields.
 *    b. For Externalizable, data layout is described by 2(b).
 * 
* *

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. * * @since 1.2 * @author Joe Fialli * @author Neal Gafter (rewrite but not too proud) */ class SerializedForm { ListBuffer methods = new ListBuffer<>(); /* List of FieldDocImpl - Serializable fields. * Singleton list if class defines Serializable fields explicitly. * Otherwise, list of default serializable fields. * 0 length list for Externalizable. */ private final ListBuffer fields = new ListBuffer<>(); /* True if class specifies serializable fields explicitly. * using special static member, serialPersistentFields. */ private boolean definesSerializableFields = false; // Specially treated field/method names defined by Serialization. private static final String SERIALIZABLE_FIELDS = "serialPersistentFields"; private static final String READOBJECT = "readObject"; private static final String WRITEOBJECT = "writeObject"; private static final String READRESOLVE = "readResolve"; private static final String WRITEREPLACE = "writeReplace"; private static final String READOBJECTNODATA = "readObjectNoData"; /** * Constructor. * * Catalog Serializable fields for Serializable class. * Catalog serialization methods for Serializable and * Externalizable classes. */ SerializedForm(DocEnv env, ClassSymbol def, ClassDocImpl cd) { if (cd.isExternalizable()) { /* look up required public accessible methods, * writeExternal and readExternal. */ String[] readExternalParamArr = { "java.io.ObjectInput" }; String[] writeExternalParamArr = { "java.io.ObjectOutput" }; MethodDoc md = cd.findMethod("readExternal", readExternalParamArr); if (md != null) { methods.append(md); } md = cd.findMethod("writeExternal", writeExternalParamArr); if (md != null) { methods.append(md); Tag tag[] = md.tags("serialData"); } // } else { // isSerializable() //### ??? } else if (cd.isSerializable()) { VarSymbol dsf = getDefinedSerializableFields(def); if (dsf != null) { /* Define serializable fields with array of ObjectStreamField. * Each ObjectStreamField should be documented by a * serialField tag. */ definesSerializableFields = true; //### No modifier filtering applied here. FieldDocImpl dsfDoc = env.getFieldDoc(dsf); fields.append(dsfDoc); mapSerialFieldTagImplsToFieldDocImpls(dsfDoc, env, def); } else { /* Calculate default Serializable fields as all * non-transient, non-static fields. * Fields should be documented by serial tag. */ computeDefaultSerializableFields(env, def, cd); } /* Check for optional customized readObject, writeObject, * readResolve and writeReplace, which can all contain * the serialData tag. */ addMethodIfExist(env, def, READOBJECT); addMethodIfExist(env, def, WRITEOBJECT); addMethodIfExist(env, def, READRESOLVE); addMethodIfExist(env, def, WRITEREPLACE); addMethodIfExist(env, def, READOBJECTNODATA); } } /* * Check for explicit Serializable fields. * Check for a private static array of ObjectStreamField with * name SERIALIZABLE_FIELDS. */ private VarSymbol getDefinedSerializableFields(ClassSymbol def) { Names names = def.name.table.names; /* SERIALIZABLE_FIELDS can be private, * so must lookup by ClassSymbol, not by ClassDocImpl. */ Scope members = SymbolKind.invokeOrNull(def, "members"); for (Symbol sym : SymbolKind.getSymbolsByName(members, true, names.fromString(SERIALIZABLE_FIELDS))) { if (SymbolKind.VAR.same(sym)) { VarSymbol f = (VarSymbol)sym; if ((f.flags() & Flags.STATIC) != 0 && (f.flags() & Flags.PRIVATE) != 0) { return f; } } } return null; } /* * Compute default Serializable fields from all members of ClassSymbol. * * Since the fields of ClassDocImpl might not contain private or * package accessible fields, must walk over all members of ClassSymbol. */ private void computeDefaultSerializableFields(DocEnv env, ClassSymbol def, ClassDocImpl cd) { Scope members = SymbolKind.invokeOrNull(def, "members"); for (Symbol sym : SymbolKind.getSymbols(members, false)) { if (sym != null && SymbolKind.VAR.same(sym)) { VarSymbol f = (VarSymbol)sym; if ((f.flags() & Flags.STATIC) == 0 && (f.flags() & Flags.TRANSIENT) == 0) { //### No modifier filtering applied here. FieldDocImpl fd = env.getFieldDoc(f); //### Add to beginning. //### Preserve order used by old 'javadoc'. fields.prepend(fd); } } } } /* * Catalog Serializable method if it exists in current ClassSymbol. * Do not look for method in superclasses. * * Serialization requires these methods to be non-static. * * @param method should be an unqualified Serializable method * name either READOBJECT, WRITEOBJECT, READRESOLVE * or WRITEREPLACE. * @param visibility the visibility flag for the given method. */ private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) { Names names = def.name.table.names; Scope members = SymbolKind.invokeOrNull(def, "members"); for (Symbol sym : SymbolKind.getSymbolsByName(members, true, names.fromString(methodName))) { if (SymbolKind.MTH.same(sym)) { MethodSymbol md = (MethodSymbol)sym; if ((md.flags() & Flags.STATIC) == 0) { /* * WARNING: not robust if unqualifiedMethodName is overloaded * method. Signature checking could make more robust. * READOBJECT takes a single parameter, java.io.ObjectInputStream. * WRITEOBJECT takes a single parameter, java.io.ObjectOutputStream. */ methods.append(env.getMethodDoc(md)); } } } } /* * Associate serialField tag fieldName with FieldDocImpl member. * Note: A serialField tag does not have to map an existing field * of a class. */ private void mapSerialFieldTagImplsToFieldDocImpls(FieldDocImpl spfDoc, DocEnv env, ClassSymbol def) { Names names = def.name.table.names; for (SerialFieldTag tag : spfDoc.serialFieldTags()) { if (tag.fieldName() == null || tag.fieldType() == null) // ignore malformed @serialField tags continue; Name fieldName = names.fromString(tag.fieldName()); // Look for a FieldDocImpl that is documented by serialFieldTagImpl. Scope members = SymbolKind.invokeOrNull(def, "members"); for (Symbol sym : SymbolKind.getSymbolsByName(members, true, fieldName)) { if (SymbolKind.VAR.same(sym)) { VarSymbol f = (VarSymbol) sym; FieldDocImpl fdi = env.getFieldDoc(f); ((SerialFieldTagImpl) (tag)).mapToFieldDocImpl(fdi); break; } } } } /** * Return serializable fields in class.

* * Returns either a list of default fields documented by serial tag comment or * javadoc comment

* Or Returns a single FieldDocImpl for serialPersistentField. There is a * serialField tag for each serializable field.

* * @return an array of FieldDocImpl for representing the visible * fields in this class. */ FieldDoc[] fields() { return (FieldDoc[])fields.toArray(new FieldDocImpl[fields.length()]); } /** * Return serialization methods in class. * * @return an array of MethodDocImpl for serialization methods in this class. */ MethodDoc[] methods() { return methods.toArray(new MethodDoc[methods.length()]); } /** * Returns true if Serializable fields are defined explicitly using * member, serialPersistentFields. * * @see #fields() */ boolean definesSerializableFields() { return definesSerializableFields; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy