001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.pack200.bytecode;
018:
019: import java.io.DataOutputStream;
020: import java.io.IOException;
021:
022: /**
023: * Abstract superclass for Annotations attributes
024: */
025: public abstract class AnnotationsAttribute extends Attribute {
026:
027: /**
028: * Class to represent the annotation structure for class file attributes
029: */
030: public static class Annotation {
031:
032: private int num_pairs;
033: private CPUTF8[] element_names;
034: private ElementValue[] element_values;
035: private CPUTF8 type;
036:
037: // Resolved values
038: private int type_index;
039: private int[] name_indexes;
040:
041: public Annotation(int num_pairs, CPUTF8 type,
042: CPUTF8[] element_names, ElementValue[] element_values) {
043: this .num_pairs = num_pairs;
044: this .type = type;
045: this .element_names = element_names;
046: this .element_values = element_values;
047: }
048:
049: public int getLength() {
050: int length = 4;
051: for (int i = 0; i < num_pairs; i++) {
052: length += 2;
053: length += element_values[i].getLength();
054: }
055: return length;
056: }
057:
058: public void resolve(ClassConstantPool pool) {
059: type.resolve(pool);
060: type_index = pool.indexOf(type);
061: name_indexes = new int[num_pairs];
062: for (int i = 0; i < element_names.length; i++) {
063: element_names[i].resolve(pool);
064: name_indexes[i] = pool.indexOf(element_names[i]);
065: element_values[i].resolve(pool);
066: }
067: }
068:
069: public void writeBody(DataOutputStream dos) throws IOException {
070: dos.writeShort(type_index);
071: dos.writeShort(num_pairs);
072: for (int i = 0; i < num_pairs; i++) {
073: dos.writeShort(name_indexes[i]);
074: element_values[i].writeBody(dos);
075: }
076: }
077:
078: }
079:
080: public static class ElementValue {
081:
082: private Object value;
083: private int tag;
084:
085: // resolved value index if it's a constant
086: private int constant_value_index = -1;
087:
088: public ElementValue(int tag, Object value) {
089: this .tag = tag;
090: this .value = value;
091: }
092:
093: public void resolve(ClassConstantPool pool) {
094: if (value instanceof CPConstant) {
095: ((CPConstant) value).resolve(pool);
096: constant_value_index = pool.indexOf((CPConstant) value);
097: } else if (value instanceof CPClass) {
098: ((CPClass) value).resolve(pool);
099: constant_value_index = pool.indexOf((CPClass) value);
100: } else if (value instanceof CPNameAndType) {
101: ((CPNameAndType) value).resolve(pool);
102: } else if (value instanceof Annotation) {
103: ((Annotation) value).resolve(pool);
104: } else if (value instanceof ElementValue[]) {
105: ElementValue[] nestedValues = (ElementValue[]) value;
106: for (int i = 0; i < nestedValues.length; i++) {
107: nestedValues[i].resolve(pool);
108: }
109: }
110: }
111:
112: public void writeBody(DataOutputStream dos) throws IOException {
113: dos.writeByte(tag);
114: if (constant_value_index != -1) {
115: dos.writeShort(constant_value_index);
116: } else if (value instanceof CPNameAndType) {
117: ((CPNameAndType) value).writeBody(dos);
118: } else if (value instanceof Annotation) {
119: ((Annotation) value).writeBody(dos);
120: } else if (value instanceof ElementValue[]) {
121: ElementValue[] nestedValues = (ElementValue[]) value;
122: for (int i = 0; i < nestedValues.length; i++) {
123: nestedValues[i].writeBody(dos);
124: }
125: }
126: }
127:
128: public int getLength() {
129: switch (tag) {
130: case 'B':
131: case 'C':
132: case 'D':
133: case 'F':
134: case 'I':
135: case 'J':
136: case 'S':
137: case 'Z':
138: case 'c':
139: return 3;
140: case 'e':
141: return 5;
142: case '[':
143: int length = 3;
144: ElementValue[] nestedValues = (ElementValue[]) value;
145: for (int i = 0; i < nestedValues.length; i++) {
146: length += nestedValues[i].getLength();
147: }
148: return length;
149: case '@':
150: return (1 + ((Annotation) value).getLength());
151: }
152: return 0;
153: }
154: }
155:
156: public AnnotationsAttribute(String attributeName) {
157: super(attributeName);
158: }
159:
160: }
|