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;
018:
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import org.apache.harmony.pack200.bytecode.AnnotationDefaultAttribute;
025: import org.apache.harmony.pack200.bytecode.Attribute;
026: import org.apache.harmony.pack200.bytecode.CPDouble;
027: import org.apache.harmony.pack200.bytecode.CPFloat;
028: import org.apache.harmony.pack200.bytecode.CPInteger;
029: import org.apache.harmony.pack200.bytecode.CPLong;
030: import org.apache.harmony.pack200.bytecode.CPNameAndType;
031: import org.apache.harmony.pack200.bytecode.CPUTF8;
032: import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
033: import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
034: import org.apache.harmony.pack200.bytecode.AnnotationsAttribute.Annotation;
035: import org.apache.harmony.pack200.bytecode.AnnotationsAttribute.ElementValue;
036: import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
037:
038: /**
039: * Group of metadata bands, e.g. class_RVA_bands, method_AD_bands etc
040: */
041: public class MetadataBandGroup {
042:
043: private String type;
044:
045: public MetadataBandGroup(String type) {
046: this .type = type;
047: }
048:
049: private List attributes;
050:
051: public int[] param_NB;
052: public int[] anno_N;
053: public CPUTF8[][] type_RS;
054: public int[][] pair_N;
055: public CPUTF8[] name_RU;
056: public int[] T;
057: public CPInteger[] caseI_KI;
058: public CPDouble[] caseD_KD;
059: public CPFloat[] caseF_KF;
060: public CPLong[] caseJ_KJ;
061: public CPUTF8[] casec_RS;
062: public String[] caseet_RS;
063: public String[] caseec_RU;
064: public CPUTF8[] cases_RU;
065: public int[] casearray_N;
066: public CPUTF8[] nesttype_RS;
067: public int[] nestpair_N;
068: public CPUTF8[] nestname_RU;
069:
070: private Iterator caseI_Iterator;
071:
072: private Iterator caseD_Iterator;
073:
074: private Iterator caseF_Iterator;
075:
076: private Iterator caseJ_Iterator;
077:
078: private Iterator casec_Iterator;
079:
080: private Iterator caseet_Iterator;
081:
082: private Iterator caseec_Iterator;
083:
084: private Iterator cases_Iterator;
085:
086: private Iterator casearray_Iterator;
087:
088: private Iterator T_iterator;
089:
090: private Iterator nesttype_RS_Iterator;
091:
092: private Iterator nestpair_N_Iterator;
093:
094: private Iterator nestname_RU_Iterator;
095:
096: private Iterator anno_N_Iterator;
097:
098: private Iterator type_RS_Iterator;
099:
100: private Iterator pair_N_Iterator;
101:
102: public List getAttributes() {
103: if (attributes == null) {
104: attributes = new ArrayList();
105: if (name_RU != null) {
106: Iterator name_RU_Iterator = Arrays.asList(name_RU)
107: .iterator();
108: if (!type.equals("AD")) {
109: T_iterator = Arrays.asList(boxArray(T)).iterator();
110: }
111: caseI_Iterator = Arrays.asList(caseI_KI).iterator();
112: caseD_Iterator = Arrays.asList(caseD_KD).iterator();
113: caseF_Iterator = Arrays.asList(caseF_KF).iterator();
114: caseJ_Iterator = Arrays.asList(caseJ_KJ).iterator();
115: casec_Iterator = Arrays.asList(casec_RS).iterator();
116: caseet_Iterator = Arrays.asList(caseet_RS).iterator();
117: caseec_Iterator = Arrays.asList(caseec_RU).iterator();
118: cases_Iterator = Arrays.asList(cases_RU).iterator();
119: casearray_Iterator = Arrays.asList(
120: boxArray(casearray_N)).iterator();
121: nesttype_RS_Iterator = Arrays.asList(nesttype_RS)
122: .iterator();
123: nestpair_N_Iterator = Arrays.asList(
124: boxArray(nestpair_N)).iterator();
125: nestname_RU_Iterator = Arrays.asList(nestname_RU)
126: .iterator();
127: if (type.equals("RVA") || type.equals("RIA")) {
128: for (int i = 0; i < anno_N.length; i++) {
129: attributes
130: .add(getAttribute(anno_N[i],
131: type_RS[i], pair_N[i],
132: name_RU_Iterator));
133: }
134: } else if (type.equals("RVPA") || type.equals("RIPA")) {
135: anno_N_Iterator = Arrays.asList(boxArray(anno_N))
136: .iterator();
137: type_RS_Iterator = Arrays.asList(type_RS)
138: .iterator();
139: pair_N_Iterator = Arrays.asList(pair_N).iterator();
140: for (int i = 0; i < param_NB.length; i++) {
141: attributes.add(getParameterAttribute(
142: param_NB[i], name_RU_Iterator));
143: }
144: } else { // type.equals("AD")
145: for (int i = 0; i < T.length; i++) {
146: attributes.add(new AnnotationDefaultAttribute(
147: new ElementValue(T[i],
148: getNextValue(T[i]))));
149: }
150: }
151: }
152: }
153: return attributes;
154: }
155:
156: private Attribute getAttribute(int numAnnotations, CPUTF8[] types,
157: int[] pairCounts, Iterator namesIterator) {
158: Annotation[] annotations = new Annotation[numAnnotations];
159: for (int i = 0; i < numAnnotations; i++) {
160: annotations[i] = getAnnotation(types[i], pairCounts[i],
161: namesIterator);
162: }
163: return new RuntimeVisibleorInvisibleAnnotationsAttribute(type
164: .equals("RVA") ? "RuntimeVisibleAnnotations"
165: : "RuntimeInvisibleAnnotations", annotations);
166: }
167:
168: private Attribute getParameterAttribute(int numParameters,
169: Iterator namesIterator) {
170: ParameterAnnotation[] parameter_annotations = new ParameterAnnotation[numParameters];
171: for (int i = 0; i < numParameters; i++) {
172: int numAnnotations = ((Integer) anno_N_Iterator.next())
173: .intValue();
174: int[] pairCounts = (int[]) pair_N_Iterator.next();
175: Annotation[] annotations = new Annotation[numAnnotations];
176: for (int j = 0; j < annotations.length; j++) {
177: annotations[j] = getAnnotation(
178: (CPUTF8) type_RS_Iterator.next(),
179: pairCounts[j], namesIterator);
180: }
181: parameter_annotations[i] = new ParameterAnnotation(
182: annotations);
183: }
184: return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(
185: type.equals("RVA") ? "RuntimeVisibleParameterAnnotations"
186: : "RuntimeInvisibleParameterAnnotations",
187: parameter_annotations);
188: }
189:
190: private Annotation getAnnotation(CPUTF8 type, int pairCount,
191: Iterator namesIterator) {
192: CPUTF8[] elementNames = new CPUTF8[pairCount];
193: ElementValue[] elementValues = new ElementValue[pairCount];
194: for (int j = 0; j < elementNames.length; j++) {
195: elementNames[j] = (CPUTF8) namesIterator.next();
196: int t = ((Integer) T_iterator.next()).intValue();
197: elementValues[j] = new ElementValue(t, getNextValue(t));
198: }
199: return new Annotation(pairCount, type, elementNames,
200: elementValues);
201: }
202:
203: private Object getNextValue(int t) {
204: switch (t) {
205: case 'B':
206: case 'C':
207: case 'I':
208: case 'S':
209: case 'Z':
210: return caseI_Iterator.next();
211: case 'D':
212: return caseD_Iterator.next();
213: case 'F':
214: return caseF_Iterator.next();
215: case 'J':
216: return caseJ_Iterator.next();
217: case 'c':
218: return casec_Iterator.next();
219: case 'e':
220: // TODO: check this - it may not work if the first string already has a colon in it
221: String enumString = caseet_Iterator.next() + ":"
222: + caseec_Iterator.next();
223: return new CPNameAndType(enumString);
224: case 's':
225: return cases_Iterator.next();
226: case '[':
227: int arraySize = ((Integer) casearray_Iterator.next())
228: .intValue();
229: ElementValue[] nestedArray = new ElementValue[arraySize];
230: for (int i = 0; i < arraySize; i++) {
231: int nextT = ((Integer) T_iterator.next()).intValue();
232: nestedArray[i] = new ElementValue(nextT,
233: getNextValue(nextT));
234: }
235: return nestedArray;
236: case '@':
237: CPUTF8 type = (CPUTF8) nesttype_RS_Iterator.next();
238: int numPairs = ((Integer) nestpair_N_Iterator.next())
239: .intValue();
240:
241: return getAnnotation(type, numPairs, nestname_RU_Iterator);
242: }
243: return null;
244: }
245:
246: private Integer[] boxArray(int[] unboxed) {
247: Integer[] boxed = new Integer[unboxed.length];
248: for (int i = 0; i < boxed.length; i++) {
249: boxed[i] = new Integer(unboxed[i]);
250: }
251: return boxed;
252: }
253:
254: }
|