/**
 * EasyBeans
 * Copyright (C) 2006 Bull S.A.S.
 * Contact: easybeans@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: SerialVersionUIDReader.java 5276 2010-01-08 16:22:04Z benoitf $
 * --------------------------------------------------------------------------
 */

package org.ow2.spec.testengine;

import java.util.ArrayList;

import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.SerialVersionUIDAdder;

public class SerialVersionUIDReader extends SerialVersionUIDAdder {

    private AnalyzerClassVisitor analyzerClassVisitor;

    public SerialVersionUIDReader(final AnalyzerClassVisitor analyzerClassVisitor) {
        super(analyzerClassVisitor);
        this.analyzerClassVisitor = analyzerClassVisitor;
    }

    /**
     * Visits the header of the class.
     * @param version the class version.
     * @param access the class's access flags (see {@link Opcodes}). This
     *        parameter also indicates if the class is deprecated.
     * @param name the internal name of the class (see
     *        {@link Type#getInternalName() getInternalName}).
     * @param signature the signature of this class. May be <tt>null</tt> if
     *        the class is not a generic one, and does not extend or implement
     *        generic classes or interfaces.
     * @param superName the internal of name of the super class (see
     *        {@link Type#getInternalName() getInternalName}). For interfaces,
     *        the super class is {@link Object}. May be <tt>null</tt>, but
     *        only for the {@link Object} class.
     * @param interfaces the internal names of the class's interfaces (see
     *        {@link Type#getInternalName() getInternalName}). May be
     *        <tt>null</tt>.
     */
    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        this.name = name;
        // reset values
        computeSVUID = true;
        hasSVUID = false;
        hasStaticInitializer = false;
        svuidFields = new ArrayList();
        svuidConstructors = new ArrayList();
        svuidMethods = new ArrayList();
        super.visit(version, access, name, signature, superName, interfaces);
        // Not serializable
        if ("java/lang/Object".equals(superName) && (interfaces == null || interfaces.length == 0)) {
            computeSVUID = false;
        }
    }

    /*
     * Gets class field information for step 4 of the alogrithm. Also determines
     * if the class already has a SVUID.
     */
    @Override
    public FieldVisitor visitField(
            final int access,
            final String name,
            final String desc,
            final String signature,
            final Object value)
    {
        FieldVisitor fv = super.visitField(access, name, desc, signature, value);
        if (name.equals("serialVersionUID")) {
            // set the value
            analyzerClassVisitor.setUID((Long) value);
        }

        return fv;

    }


    @Override
    public void visitEnd() {
        // Set the id if it was computed
        if (computeSVUID) {
            try {
                analyzerClassVisitor.setUID(new Long(computeSVUID()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        cv.visitEnd();
    }

}
