alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SerializedForm.java)

This example Java source code file (SerializedForm.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

classdocimpl, classsymbol, fielddocimpl, javadoc, listbuffer, methoddoc, names, readobject, readobjectnodata, readresolve, serializedform, string, varsymbol, writeobject, writereplace

The SerializedForm.java Java example source code

/*
 * Copyright (c) 1998, 2012, 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.javadoc;

import com.sun.javadoc.*;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
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.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;

/**
 * The serialized form is the specification of a class' serialization
 * state. <p>
 *
 * It consists of the following information:<p>
 *
 * <pre>
 * 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).
 * </pre>
 *
 *  <p>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.</b>
 *
 * @since 1.2
 * @author Joe Fialli
 * @author Neal Gafter (rewrite but not too proud)
 */
class SerializedForm {
    ListBuffer<MethodDoc> 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<FieldDocImpl> 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.
         */
        for (Scope.Entry e = def.members().lookup(names.fromString(SERIALIZABLE_FIELDS)); e.scope != null; e = e.next()) {
            if (e.sym.kind == Kinds.VAR) {
                VarSymbol f = (VarSymbol)e.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) {
        for (Scope.Entry e = def.members().elems; e != null; e = e.sibling) {
            if (e.sym != null && e.sym.kind == Kinds.VAR) {
                VarSymbol f = (VarSymbol)e.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;

        for (Scope.Entry e = def.members().lookup(names.fromString(methodName)); e.scope != null; e = e.next()) {
            if (e.sym.kind == Kinds.MTH) {
                MethodSymbol md = (MethodSymbol)e.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;

        SerialFieldTag[] sfTag = spfDoc.serialFieldTags();
        for (int i = 0; i < sfTag.length; i++) {
            if (sfTag[i].fieldName() == null || sfTag[i].fieldType() == null) // ignore malformed @serialField tags
                continue;

            Name fieldName = names.fromString(sfTag[i].fieldName());

            // Look for a FieldDocImpl that is documented by serialFieldTagImpl.
            for (Scope.Entry e = def.members().lookup(fieldName); e.scope != null; e = e.next()) {
                if (e.sym.kind == Kinds.VAR) {
                    VarSymbol f = (VarSymbol)e.sym;
                    FieldDocImpl fdi = env.getFieldDoc(f);
                    ((SerialFieldTagImpl)(sfTag[i])).mapToFieldDocImpl(fdi);
                    break;
                }
            }
        }
    }

    /**
     * Return serializable fields in class. <p>
     *
     * Returns either a list of default fields documented by serial tag comment or
     *         javadoc comment<p>
     * Or Returns a single FieldDocImpl for serialPersistentField. There is a
     *         serialField tag for each serializable field.<p>
     *
     * @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;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java SerializedForm.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.