Package org.cojen.classfile

Source Code of org.cojen.classfile.FieldInfo

/*
*  Copyright 2004-2010 Brian S O'Neill
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.cojen.classfile;

import java.util.ArrayList;
import java.util.List;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Modifier;
import org.cojen.classfile.attribute.Annotation;
import org.cojen.classfile.attribute.AnnotationsAttr;
import org.cojen.classfile.attribute.ConstantValueAttr;
import org.cojen.classfile.attribute.DeprecatedAttr;
import org.cojen.classfile.attribute.RuntimeInvisibleAnnotationsAttr;
import org.cojen.classfile.attribute.RuntimeVisibleAnnotationsAttr;
import org.cojen.classfile.attribute.SignatureAttr;
import org.cojen.classfile.attribute.SyntheticAttr;
import org.cojen.classfile.constant.ConstantUTFInfo;

/**
* This class corresponds to the field_info structure as defined in <i>The Java
* Virtual Machine Specification</i>.
*
* @author Brian S O'Neill
* @see ClassFile
*/
public class FieldInfo {
    private ClassFile mParent;
    private ConstantPool mCp;

    private String mName;
    private TypeDesc mType;

    private Modifiers mModifiers;

    private ConstantUTFInfo mNameConstant;
    private ConstantUTFInfo mDescriptorConstant;
   
    private List<Attribute> mAttributes = new ArrayList<Attribute>(2);

    private ConstantValueAttr mConstant;
   
    FieldInfo(ClassFile parent,
              Modifiers modifiers,
              String name,
              TypeDesc type) {

        mParent = parent;
        mCp = parent.getConstantPool();
        mName = name;
        mType = type;

        mModifiers = modifiers;
        mNameConstant = mCp.addConstantUTF(name);
        mDescriptorConstant = mCp.addConstantUTF(type.getDescriptor());
    }
   
    private FieldInfo(ClassFile parent,
                      int modifier,
                      ConstantUTFInfo nameConstant,
                      ConstantUTFInfo descConstant) {

        mParent = parent;
        mCp = parent.getConstantPool();
        mName = nameConstant.getValue();
        mType = TypeDesc.forDescriptor(descConstant.getValue());

        mModifiers = Modifiers.getInstance(modifier);
        mNameConstant = nameConstant;
        mDescriptorConstant = descConstant;
    }

    /**
     * Returns the parent ClassFile for this FieldInfo.
     */
    public ClassFile getClassFile() {
        return mParent;
    }

    /**
     * Returns the name of this field.
     */
    public String getName() {
        return mName;
    }

    /**
     * Returns the type of this field.
     */
    public TypeDesc getType() {
        return mType;
    }
   
    /**
     * Returns this field's modifiers.
     */
    public Modifiers getModifiers() {
        return mModifiers;
    }

    public void setModifiers(Modifiers modifiers) {
        mModifiers = modifiers;
    }

    /**
     * Returns a constant from the constant pool with this field's name.
     */
    public ConstantUTFInfo getNameConstant() {
        return mNameConstant;
    }
   
    /**
     * Returns a constant from the constant pool with this field's type
     * descriptor string.
     * @see TypeDesc
     */
    public ConstantUTFInfo getDescriptorConstant() {
        return mDescriptorConstant;
    }

    /**
     * Returns the constant value for this field or null if no constant set.
     */
    public ConstantInfo getConstantValue() {
        if (mConstant == null) {
            return null;
        } else {
            return mConstant.getConstant();
        }
    }

    public boolean isSynthetic() {
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute attr = mAttributes.get(i);
            if (attr instanceof SyntheticAttr) {
                return true;
            }
        }
        return false;
    }

    public boolean isDeprecated() {
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute attr = mAttributes.get(i);
            if (attr instanceof DeprecatedAttr) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns all the runtime invisible annotations defined for this class
     * file, or an empty array if none.
     */
    public Annotation[] getRuntimeInvisibleAnnotations() {
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute attr = mAttributes.get(i);
            if (attr instanceof RuntimeInvisibleAnnotationsAttr) {
                return ((AnnotationsAttr) attr).getAnnotations();
            }
        }
        return new Annotation[0];
    }

    /**
     * Returns all the runtime visible annotations defined for this class file,
     * or an empty array if none.
     */
    public Annotation[] getRuntimeVisibleAnnotations() {
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute attr = mAttributes.get(i);
            if (attr instanceof RuntimeVisibleAnnotationsAttr) {
                return ((AnnotationsAttr) attr).getAnnotations();
            }
        }
        return new Annotation[0];
    }

    /**
     * Add a runtime invisible annotation.
     */
    public Annotation addRuntimeInvisibleAnnotation(TypeDesc type) {
        AnnotationsAttr attr = null;
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute a = mAttributes.get(i);
            if (a instanceof RuntimeInvisibleAnnotationsAttr) {
                attr = (AnnotationsAttr) a;
            }
        }
        if (attr == null) {
            attr = new RuntimeInvisibleAnnotationsAttr(mCp);
            addAttribute(attr);
        }
        Annotation ann = new Annotation(mCp);
        ann.setType(type);
        attr.addAnnotation(ann);
        return ann;
    }

    /**
     * Add a runtime visible annotation.
     */
    public Annotation addRuntimeVisibleAnnotation(TypeDesc type) {
        AnnotationsAttr attr = null;
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute a = mAttributes.get(i);
            if (a instanceof RuntimeVisibleAnnotationsAttr) {
                attr = (AnnotationsAttr) a;
            }
        }
        if (attr == null) {
            attr = new RuntimeVisibleAnnotationsAttr(mCp);
            addAttribute(attr);
        }
        Annotation ann = new Annotation(mCp);
        ann.setType(type);
        attr.addAnnotation(ann);
        return ann;
    }

    /**
     * Returns the signature attribute of this field, or null if none is
     * defined.
     */
    // TODO: Eventually remove this method
    public SignatureAttr getSignatureAttr() {
        for (int i = mAttributes.size(); --i >= 0; ) {
            Attribute attr = mAttributes.get(i);
            if (attr instanceof SignatureAttr) {
                return (SignatureAttr) attr;
            }
        }
        return null;
    }

    /**
     * Set the constant value for this field as an int.
     */
    public void setConstantValue(int value) {
        addAttribute(new ConstantValueAttr(mCp, mCp.addConstantInteger(value)));
    }

    /**
     * Set the constant value for this field as a float.
     */
    public void setConstantValue(float value) {
        addAttribute(new ConstantValueAttr(mCp, mCp.addConstantFloat(value)));
    }

    /**
     * Set the constant value for this field as a long.
     */
    public void setConstantValue(long value) {
        addAttribute(new ConstantValueAttr(mCp, mCp.addConstantLong(value)));
    }

    /**
     * Set the constant value for this field as a double.
     */
    public void setConstantValue(double value) {
        addAttribute(new ConstantValueAttr(mCp, mCp.addConstantDouble(value)));
    }

    /**
     * Set the constant value for this field as a string.
     */
    public void setConstantValue(String value) {
        addAttribute(new ConstantValueAttr(mCp, mCp.addConstantString(value)));
    }
   
    /**
     * Mark this field as being synthetic by adding a special attribute.
     */
    public void markSynthetic() {
        addAttribute(new SyntheticAttr(mCp));
    }

    /**
     * Mark this field as being deprecated by adding a special attribute.
     */
    public void markDeprecated() {
        addAttribute(new DeprecatedAttr(mCp));
    }

    public void addAttribute(Attribute attr) {
        if (attr instanceof ConstantValueAttr) {
            if (mConstant != null) {
                mAttributes.remove(mConstant);
            }
            mConstant = (ConstantValueAttr)attr;
        }

        mAttributes.add(attr);
    }

    public Attribute[] getAttributes() {
        return mAttributes.toArray(new Attribute[mAttributes.size()]);
    }
   
    /**
     * Returns the length (in bytes) of this object in the class file.
     */
    public int getLength() {
        int length = 8;
       
        int size = mAttributes.size();
        for (int i=0; i<size; i++) {
            length += mAttributes.get(i).getLength();
        }
       
        return length;
    }
   
    public void writeTo(DataOutput dout) throws IOException {
        dout.writeShort(mModifiers.getBitmask());
        dout.writeShort(mNameConstant.getIndex());
        dout.writeShort(mDescriptorConstant.getIndex());
       
        int size = mAttributes.size();
        dout.writeShort(size);
        for (int i=0; i<size; i++) {
            Attribute attr = mAttributes.get(i);
            attr.writeTo(dout);
        }
    }

    public String toString() {
        String modStr = mModifiers.toString();
        String typeStr;
        if (modStr.length() == 0) {
            return mType.getFullName() + ' ' + getName();
        } else {
            return modStr + ' ' + mType.getFullName() + ' ' + getName();
        }
    }

    static FieldInfo readFrom(ClassFile parent,
                              DataInput din,
                              AttributeFactory attrFactory)
        throws IOException
    {
        ConstantPool cp = parent.getConstantPool();

        int modifier = din.readUnsignedShort();
        int index = din.readUnsignedShort();
        ConstantUTFInfo nameConstant = (ConstantUTFInfo)cp.getConstant(index);
        index = din.readUnsignedShort();
        ConstantUTFInfo descConstant = (ConstantUTFInfo)cp.getConstant(index);

        FieldInfo info = new FieldInfo(parent, modifier, nameConstant, descConstant);

        // Read attributes.
        int size = din.readUnsignedShort();
        for (int i=0; i<size; i++) {
            info.addAttribute(Attribute.readFrom(cp, din, attrFactory));
        }

        return info;
    }
}
TOP

Related Classes of org.cojen.classfile.FieldInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.