javap/src/main/java/org/apidesign/javap/AnnotationParser.java
author Martin Soch <Martin.Soch@oracle.com>
Wed, 06 Feb 2013 17:03:26 +0100
brancharithmetic
changeset 689 f87c33d2fa7b
parent 249 001389026dbf
child 405 e41809be6106
child 652 f095ea52f417
permissions -rw-r--r--
merge with trunk
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@237
    37
    private final boolean textual;
jaroslav@237
    38
    
jaroslav@237
    39
    protected AnnotationParser(boolean textual) {
jaroslav@237
    40
        this.textual = textual;
jaroslav@152
    41
    }
jaroslav@152
    42
jaroslav@235
    43
    protected void visitAnnotationStart(String type) throws IOException {
jaroslav@235
    44
    }
jaroslav@235
    45
jaroslav@235
    46
    protected void visitAnnotationEnd(String type) throws IOException {
jaroslav@235
    47
    }
jaroslav@235
    48
    
jaroslav@235
    49
    protected void visitAttr(
jaroslav@236
    50
        String annoType, String attr, String attrType, String value
jaroslav@235
    51
    ) throws IOException {
jaroslav@152
    52
    }
jaroslav@152
    53
    
jaroslav@152
    54
    /** Initialize the parsing with constant pool from <code>cd</code>.
jaroslav@152
    55
     * 
jaroslav@152
    56
     * @param attr the attribute defining annotations
jaroslav@152
    57
     * @param cd constant pool
jaroslav@152
    58
     * @throws IOException in case I/O fails
jaroslav@152
    59
     */
jaroslav@152
    60
    public final void parse(byte[] attr, ClassData cd) throws IOException {
jaroslav@152
    61
        ByteArrayInputStream is = new ByteArrayInputStream(attr);
jaroslav@152
    62
        DataInputStream dis = new DataInputStream(is);
jaroslav@152
    63
        try {
jaroslav@152
    64
            read(dis, cd);
jaroslav@152
    65
        } finally {
jaroslav@152
    66
            is.close();
jaroslav@152
    67
        }
jaroslav@152
    68
    }
jaroslav@152
    69
    
jaroslav@152
    70
    private void read(DataInputStream dis, ClassData cd) throws IOException {
jaroslav@152
    71
    	int cnt = dis.readUnsignedShort();
jaroslav@152
    72
        for (int i = 0; i < cnt; i++) {
jaroslav@152
    73
            readAnno(dis, cd);
jaroslav@152
    74
        }
jaroslav@152
    75
    }
jaroslav@152
    76
jaroslav@152
    77
    private void readAnno(DataInputStream dis, ClassData cd) throws IOException {
jaroslav@152
    78
        int type = dis.readUnsignedShort();
jaroslav@152
    79
        String typeName = cd.StringValue(type);
jaroslav@235
    80
        visitAnnotationStart(typeName);
jaroslav@152
    81
    	int cnt = dis.readUnsignedShort();
jaroslav@152
    82
    	for (int i = 0; i < cnt; i++) {
jaroslav@153
    83
            String attrName = cd.StringValue(dis.readUnsignedShort());
jaroslav@153
    84
            readValue(dis, cd, typeName, attrName);
jaroslav@152
    85
        }
jaroslav@235
    86
        visitAnnotationEnd(typeName);
jaroslav@240
    87
        if (cnt == 0) {
jaroslav@249
    88
            visitAttr(typeName, null, null, null);
jaroslav@240
    89
        }
jaroslav@152
    90
    }
jaroslav@152
    91
jaroslav@153
    92
    private void readValue(DataInputStream dis, ClassData cd, String typeName, String attrName) 
jaroslav@152
    93
    throws IOException {
jaroslav@152
    94
        char type = (char)dis.readByte();
jaroslav@152
    95
        if (type == '@') {
jaroslav@152
    96
            readAnno(dis, cd);
jaroslav@152
    97
        } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
jaroslav@152
    98
            int primitive = dis.readUnsignedShort();
jaroslav@237
    99
            String val = cd.stringValue(primitive, textual);
jaroslav@236
   100
            String attrType;
jaroslav@236
   101
            if (type == 's') {
jaroslav@252
   102
                attrType = "Ljava_lang_String_2";
jaroslav@237
   103
                if (textual) {
jaroslav@237
   104
                    val = '"' + val + '"';
jaroslav@237
   105
                }
jaroslav@236
   106
            } else {
jaroslav@236
   107
                attrType = "" + type;
jaroslav@236
   108
            }
jaroslav@237
   109
            visitAttr(typeName, attrName, attrType, val);
jaroslav@152
   110
        } else if (type == 'c') {
jaroslav@152
   111
            int cls = dis.readUnsignedShort();
jaroslav@152
   112
        } else if (type == '[') {
jaroslav@152
   113
            int cnt = dis.readUnsignedShort();
jaroslav@152
   114
            for (int i = 0; i < cnt; i++) {
jaroslav@153
   115
                readValue(dis, cd, typeName, attrName);
jaroslav@152
   116
            }
jaroslav@152
   117
        } else if (type == 'e') {
jaroslav@152
   118
            int enumT = dis.readUnsignedShort();
jaroslav@152
   119
            int enumN = dis.readUnsignedShort();
jaroslav@152
   120
        } else {
jaroslav@152
   121
            throw new IOException("Unknown type " + type);
jaroslav@152
   122
        }
jaroslav@152
   123
    }
jaroslav@152
   124
}