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

com.googlecode.jpattern.org.cojen.classfile.attribute.Annotation Maven / Gradle / Ivy

Go to download

This is a copy of the good Cojen project from http://cojen.sourceforge.net/ with package name changed

The newest version!
/*
 *  Copyright 2005-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 com.googlecode.jpattern.org.cojen.classfile.attribute;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import com.googlecode.jpattern.org.cojen.classfile.ConstantInfo;
import com.googlecode.jpattern.org.cojen.classfile.ConstantPool;
import com.googlecode.jpattern.org.cojen.classfile.TypeDesc;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantClassInfo;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantDoubleInfo;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantFloatInfo;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantIntegerInfo;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantLongInfo;
import com.googlecode.jpattern.org.cojen.classfile.constant.ConstantUTFInfo;

/**
 * Defines the annotation structure used by Java 5 annotations attributes.
 *
 * @author Brian S O'Neill
 */
public class Annotation {

    /** Member value is represented by a ConstantIntegerInfo */
    public static final char MEMBER_TAG_BOOLEAN = 'Z';
    
    /** Member value is represented by a ConstantIntegerInfo */
    public static final char MEMBER_TAG_BYTE = 'B';
    
    /** Member value is represented by a ConstantIntegerInfo */
    public static final char MEMBER_TAG_SHORT = 'S';
    
    /** Member value is represented by a ConstantIntegerInfo */
    public static final char MEMBER_TAG_CHAR = 'C';
    
    /** Member value is represented by a ConstantIntegerInfo */
    public static final char MEMBER_TAG_INT = 'I';
    
    /** Member value is represented by a ConstantLongInfo */
    public static final char MEMBER_TAG_LONG = 'J';
        
    /** Member value is represented by a ConstantFloatInfo */
    public static final char MEMBER_TAG_FLOAT = 'F';

    /** Member value is represented by a ConstantDoubleInfo */
    public static final char MEMBER_TAG_DOUBLE = 'D';

    /** Member value is represented by a ConstantUTFInfo */
    public static final char MEMBER_TAG_STRING = 's';

    /** Member value is represented by a ConstantClassInfo */
    public static final char MEMBER_TAG_CLASS = 'c';

    /** Member value is represented by an EnumConstValue */
    public static final char MEMBER_TAG_ENUM = 'e';

    /** Member value is represented by a MemberValue array */
    public static final char MEMBER_TAG_ARRAY = '[';

    /** Member value is represented by an Annotation */
    public static final char MEMBER_TAG_ANNOTATION = '@';

    private final ConstantPool mCp;
    private ConstantUTFInfo mType;
    private final Map mMemberValues;
    
    public Annotation(ConstantPool cp) {
        mCp = cp;
        mMemberValues = new LinkedHashMap(2);
    }
    
    public Annotation(ConstantPool cp, DataInput din) throws IOException {
        mCp = cp;
        mType = (ConstantUTFInfo)cp.getConstant(din.readUnsignedShort());

        int memberCount = din.readUnsignedShort();
        mMemberValues = new LinkedHashMap(memberCount);
        
        for (int i=0; i getMemberValues() {
        return Collections.unmodifiableMap(mMemberValues);
    }
    
    public void putMemberValue(String name, MemberValue mv) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, mv);
    }

    public void putMemberValue(String name, boolean value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, byte value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }
    
    public void putMemberValue(String name, short value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, char value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, int value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, long value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, float value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, double value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, String value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, TypeDesc value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, MemberValue[] value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public void putMemberValue(String name, TypeDesc enumType, String enumName) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(enumType, enumName));
    }

    /**
     * @see #makeAnnotation
     */
    public void putMemberValue(String name, Annotation value) {
        mCp.addConstantUTF(name);
        mMemberValues.put(name, makeMemberValue(value));
    }

    public MemberValue makeMemberValue(boolean value) {
        return new MemberValue(MEMBER_TAG_BOOLEAN, mCp.addConstantInteger(value ? 1 : 0));
    }

    public MemberValue makeMemberValue(byte value) {
        return new MemberValue(MEMBER_TAG_BYTE, mCp.addConstantInteger(value));
    }
    
    public MemberValue makeMemberValue(short value) {
        return new MemberValue(MEMBER_TAG_SHORT, mCp.addConstantInteger(value));
    }

    public MemberValue makeMemberValue(char value) {
        return new MemberValue(MEMBER_TAG_CHAR, mCp.addConstantInteger(value));
    }
    
    public MemberValue makeMemberValue(int value) {
        return new MemberValue(MEMBER_TAG_INT, mCp.addConstantInteger(value));
    }
    
    public MemberValue makeMemberValue(long value) {
        return new MemberValue(MEMBER_TAG_LONG, mCp.addConstantLong(value));
    }
    
    public MemberValue makeMemberValue(float value) {
        return new MemberValue(MEMBER_TAG_FLOAT, mCp.addConstantFloat(value));
    }
    
    public MemberValue makeMemberValue(double value) {
        return new MemberValue(MEMBER_TAG_DOUBLE, mCp.addConstantDouble(value));
    }
    
    public MemberValue makeMemberValue(String value) {
        return new MemberValue(MEMBER_TAG_STRING, mCp.addConstantUTF(value));
    }

    public MemberValue makeMemberValue(TypeDesc value) {
        return new MemberValue(MEMBER_TAG_CLASS, mCp.addConstantUTF(value.getDescriptor()));
    }
    
    public MemberValue makeMemberValue(TypeDesc enumType, String enumName) {
        return new MemberValue(MEMBER_TAG_ENUM,
                               new EnumConstValue(mCp.addConstantUTF(enumType.getDescriptor()),
                                                  mCp.addConstantUTF(enumName)));
    }

    public MemberValue makeMemberValue(MemberValue[] value) {
        return new MemberValue(MEMBER_TAG_ARRAY, value);
    }

    /**
     * @see #makeAnnotation
     */
    public MemberValue makeMemberValue(Annotation value) {
        return new MemberValue(MEMBER_TAG_ANNOTATION, value);
    }

    public Annotation makeAnnotation() {
        return new Annotation(mCp);
    }

    public int getLength() {
        int length = 4;
        for (MemberValue mv : mMemberValues.values()) {
            length += 2 + mv.getLength();
        }
        return length;
    }
    
    public void writeTo(DataOutput dout) throws IOException {
        dout.writeShort(mType.getIndex());
        int memberCount = mMemberValues.size();
        dout.writeShort(memberCount);
        for (Map.Entry entry : mMemberValues.entrySet()) {
            dout.writeShort(mCp.addConstantUTF(entry.getKey()).getIndex());
            entry.getValue().writeTo(dout);
        }
    }

    public static class MemberValue {
        private final char mTag;
        private final Object mValue;
        
        public MemberValue(char tag, Object value) {
            switch (mTag = tag) {
            default:
                throw new IllegalArgumentException
                    ("Illegal annotation member value tag: " + mTag);
                
            case MEMBER_TAG_BOOLEAN:
            case MEMBER_TAG_BYTE:
            case MEMBER_TAG_SHORT:
            case MEMBER_TAG_CHAR:
            case MEMBER_TAG_INT:
                if (value instanceof ConstantIntegerInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantIntegerInfo");
                }
                break;

            case MEMBER_TAG_LONG:
                if (value instanceof ConstantLongInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantLongInfo");
                }
                break;

            case MEMBER_TAG_FLOAT:
                if (value instanceof ConstantFloatInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantFloatInfo");
                }
                break;

            case MEMBER_TAG_DOUBLE:
                if (value instanceof ConstantDoubleInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantDoubleInfo");
                }
                break;

            case MEMBER_TAG_CLASS:
                if (value instanceof ConstantUTFInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantUTFInfo");
                }
                break;

            case MEMBER_TAG_STRING:
                if (value instanceof ConstantUTFInfo) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be ConstantUTFInfo");
                }
                break;
                
            case MEMBER_TAG_ENUM:
                if (value instanceof EnumConstValue) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be EnumConstValue");
                }
                break;
                
            case MEMBER_TAG_ARRAY:
                if (value instanceof MemberValue[]) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be MemberValue[]");
                }
                break;
                
            case MEMBER_TAG_ANNOTATION:
                if (value instanceof Annotation) {
                    mValue = value;
                } else {
                    throw new IllegalArgumentException("Value must be Annotation");
                }
                break;
            }
        }
        
        public MemberValue(ConstantPool cp, DataInput din) throws IOException {
            switch (mTag = (char)din.readUnsignedByte()) {
            default:
                throw new IllegalStateException
                    ("Illegal annotation member value tag: " + mTag);
                
            case MEMBER_TAG_BOOLEAN:
            case MEMBER_TAG_BYTE:
            case MEMBER_TAG_SHORT:
            case MEMBER_TAG_CHAR:
            case MEMBER_TAG_INT:
            case MEMBER_TAG_LONG:
            case MEMBER_TAG_FLOAT:
            case MEMBER_TAG_DOUBLE:
            case MEMBER_TAG_CLASS:
            case MEMBER_TAG_STRING:
                mValue = cp.getConstant(din.readUnsignedShort());
                break;
                
            case MEMBER_TAG_ENUM:
                mValue = new EnumConstValue(cp, din);
                break;
                
            case MEMBER_TAG_ARRAY:
                int length = din.readUnsignedShort();
                MemberValue[] values = new MemberValue[length];
                for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy