javap/src/main/java/org/apidesign/javap/AnnotationParser.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 02 Dec 2012 12:39:51 +0100
branchreflection
changeset 236 d97770281580
parent 235 bf0a77f029c4
child 237 84ffc347412d
permissions -rw-r--r--
Using the attribute type to in the attribute method name
jaroslav@152
     1
/*
jaroslav@152
     2
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
jaroslav@152
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@152
     4
 *
jaroslav@152
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@152
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@152
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@152
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@152
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@152
    10
 *
jaroslav@152
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@152
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@152
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@152
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@152
    15
 * accompanied this code).
jaroslav@152
    16
 *
jaroslav@152
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@152
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@152
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@152
    20
 *
jaroslav@152
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@152
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@152
    23
 * questions.
jaroslav@152
    24
 */
jtulach@167
    25
package org.apidesign.javap;
jaroslav@152
    26
jaroslav@152
    27
import java.io.ByteArrayInputStream;
jaroslav@152
    28
import java.io.DataInputStream;
jaroslav@152
    29
import java.io.IOException;
jaroslav@152
    30
jaroslav@152
    31
/** An abstract parser for annotation definitions. Analyses the bytes and
jaroslav@152
    32
 * performs some callbacks to the overriden parser methods.
jaroslav@152
    33
 *
jaroslav@152
    34
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@152
    35
 */
jaroslav@152
    36
public class AnnotationParser {
jaroslav@152
    37
    protected AnnotationParser() {
jaroslav@152
    38
    }
jaroslav@152
    39
jaroslav@235
    40
    protected void visitAnnotationStart(String type) throws IOException {
jaroslav@235
    41
    }
jaroslav@235
    42
jaroslav@235
    43
    protected void visitAnnotationEnd(String type) throws IOException {
jaroslav@235
    44
    }
jaroslav@235
    45
    
jaroslav@235
    46
    protected void visitAttr(
jaroslav@236
    47
        String annoType, String attr, String attrType, String value
jaroslav@235
    48
    ) throws IOException {
jaroslav@152
    49
    }
jaroslav@152
    50
    
jaroslav@152
    51
    /** Initialize the parsing with constant pool from <code>cd</code>.
jaroslav@152
    52
     * 
jaroslav@152
    53
     * @param attr the attribute defining annotations
jaroslav@152
    54
     * @param cd constant pool
jaroslav@152
    55
     * @throws IOException in case I/O fails
jaroslav@152
    56
     */
jaroslav@152
    57
    public final void parse(byte[] attr, ClassData cd) throws IOException {
jaroslav@152
    58
        ByteArrayInputStream is = new ByteArrayInputStream(attr);
jaroslav@152
    59
        DataInputStream dis = new DataInputStream(is);
jaroslav@152
    60
        try {
jaroslav@152
    61
            read(dis, cd);
jaroslav@152
    62
        } finally {
jaroslav@152
    63
            is.close();
jaroslav@152
    64
        }
jaroslav@152
    65
    }
jaroslav@152
    66
    
jaroslav@152
    67
    private void read(DataInputStream dis, ClassData cd) throws IOException {
jaroslav@152
    68
    	int cnt = dis.readUnsignedShort();
jaroslav@152
    69
        for (int i = 0; i < cnt; i++) {
jaroslav@152
    70
            readAnno(dis, cd);
jaroslav@152
    71
        }
jaroslav@152
    72
    }
jaroslav@152
    73
jaroslav@152
    74
    private void readAnno(DataInputStream dis, ClassData cd) throws IOException {
jaroslav@152
    75
        int type = dis.readUnsignedShort();
jaroslav@152
    76
        String typeName = cd.StringValue(type);
jaroslav@235
    77
        visitAnnotationStart(typeName);
jaroslav@152
    78
    	int cnt = dis.readUnsignedShort();
jaroslav@152
    79
    	for (int i = 0; i < cnt; i++) {
jaroslav@153
    80
            String attrName = cd.StringValue(dis.readUnsignedShort());
jaroslav@153
    81
            readValue(dis, cd, typeName, attrName);
jaroslav@152
    82
        }
jaroslav@235
    83
        visitAnnotationEnd(typeName);
jaroslav@152
    84
    }
jaroslav@152
    85
jaroslav@153
    86
    private void readValue(DataInputStream dis, ClassData cd, String typeName, String attrName) 
jaroslav@152
    87
    throws IOException {
jaroslav@152
    88
        char type = (char)dis.readByte();
jaroslav@152
    89
        if (type == '@') {
jaroslav@152
    90
            readAnno(dis, cd);
jaroslav@152
    91
        } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
jaroslav@152
    92
            int primitive = dis.readUnsignedShort();
jaroslav@236
    93
            String attrType;
jaroslav@236
    94
            if (type == 's') {
jaroslav@236
    95
                attrType = "Ljava_lang_String";
jaroslav@236
    96
            } else {
jaroslav@236
    97
                attrType = "" + type;
jaroslav@236
    98
            }
jaroslav@236
    99
            visitAttr(typeName, attrName, attrType, cd.StringValue(primitive));
jaroslav@152
   100
        } else if (type == 'c') {
jaroslav@152
   101
            int cls = dis.readUnsignedShort();
jaroslav@152
   102
        } else if (type == '[') {
jaroslav@152
   103
            int cnt = dis.readUnsignedShort();
jaroslav@152
   104
            for (int i = 0; i < cnt; i++) {
jaroslav@153
   105
                readValue(dis, cd, typeName, attrName);
jaroslav@152
   106
            }
jaroslav@152
   107
        } else if (type == 'e') {
jaroslav@152
   108
            int enumT = dis.readUnsignedShort();
jaroslav@152
   109
            int enumN = dis.readUnsignedShort();
jaroslav@152
   110
        } else {
jaroslav@152
   111
            throw new IOException("Unknown type " + type);
jaroslav@152
   112
        }
jaroslav@152
   113
    }
jaroslav@152
   114
}