1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.unpack200;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationDefaultAttribute;
27 import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
28 import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
29 import org.apache.commons.compress.harmony.unpack200.bytecode.Attribute;
30 import org.apache.commons.compress.harmony.unpack200.bytecode.CPDouble;
31 import org.apache.commons.compress.harmony.unpack200.bytecode.CPFloat;
32 import org.apache.commons.compress.harmony.unpack200.bytecode.CPInteger;
33 import org.apache.commons.compress.harmony.unpack200.bytecode.CPLong;
34 import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
35 import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
36 import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
37 import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
38
39
40
41
42 public class MetadataBandGroup {
43
44 private static CPUTF8 rvaUTF8;
45 private static CPUTF8 riaUTF8;
46
47 private static CPUTF8 rvpaUTF8;
48 private static CPUTF8 ripaUTF8;
49
50 public static void setRiaAttributeName(final CPUTF8 cpUTF8Value) {
51 riaUTF8 = cpUTF8Value;
52 }
53
54 public static void setRipaAttributeName(final CPUTF8 cpUTF8Value) {
55 ripaUTF8 = cpUTF8Value;
56 }
57
58 public static void setRvaAttributeName(final CPUTF8 cpUTF8Value) {
59 rvaUTF8 = cpUTF8Value;
60 }
61
62 public static void setRvpaAttributeName(final CPUTF8 cpUTF8Value) {
63 rvpaUTF8 = cpUTF8Value;
64 }
65
66 private final String type;
67
68 private final CpBands cpBands;
69
70 private List<Attribute> attributes;
71
72 public int[] param_NB;
73
74 public int[] anno_N;
75 public CPUTF8[][] type_RS;
76 public int[][] pair_N;
77 public CPUTF8[] name_RU;
78 public int[] T;
79 public CPInteger[] caseI_KI;
80 public CPDouble[] caseD_KD;
81 public CPFloat[] caseF_KF;
82 public CPLong[] caseJ_KJ;
83 public CPUTF8[] casec_RS;
84 public String[] caseet_RS;
85 public String[] caseec_RU;
86 public CPUTF8[] cases_RU;
87 public int[] casearray_N;
88 public CPUTF8[] nesttype_RS;
89 public int[] nestpair_N;
90 public CPUTF8[] nestname_RU;
91 private int caseI_KI_Index;
92
93 private int caseD_KD_Index;
94
95 private int caseF_KF_Index;
96
97 private int caseJ_KJ_Index;
98
99 private int casec_RS_Index;
100
101 private int caseet_RS_Index;
102
103 private int caseec_RU_Index;
104
105 private int cases_RU_Index;
106
107 private int casearray_N_Index;
108
109 private int T_index;
110
111 private int nesttype_RS_Index;
112
113 private int nestpair_N_Index;
114
115 private Iterator<CPUTF8> nestname_RU_Iterator;
116
117 private int anno_N_Index;
118
119 private int pair_N_Index;
120
121 public MetadataBandGroup(final String type, final CpBands cpBands) {
122 this.type = type;
123 this.cpBands = cpBands;
124 }
125
126
127
128
129
130
131
132
133 private Annotation getAnnotation(final CPUTF8 type, final int pairCount, final Iterator<CPUTF8> namesIterator) {
134 final CPUTF8[] elementNames = new CPUTF8[pairCount];
135 final ElementValue[] elementValues = new ElementValue[pairCount];
136 for (int j = 0; j < elementNames.length; j++) {
137 elementNames[j] = namesIterator.next();
138 final int t = T[T_index++];
139 elementValues[j] = new ElementValue(t, getNextValue(t));
140 }
141 return new Annotation(pairCount, type, elementNames, elementValues);
142 }
143
144 private Attribute getAttribute(final int numAnnotations, final CPUTF8[] types, final int[] pairCounts, final Iterator<CPUTF8> namesIterator) {
145 final Annotation[] annotations = new Annotation[numAnnotations];
146 Arrays.setAll(annotations, i -> getAnnotation(types[i], pairCounts[i], namesIterator));
147 return new RuntimeVisibleorInvisibleAnnotationsAttribute(type.equals("RVA") ? rvaUTF8 : riaUTF8, annotations);
148 }
149
150 public List<Attribute> getAttributes() {
151
152 if (attributes == null) {
153 attributes = new ArrayList<>();
154 if (name_RU != null) {
155 final Iterator<CPUTF8> name_RU_Iterator = Arrays.asList(name_RU).iterator();
156 if (!type.equals("AD")) {
157 T_index = 0;
158 }
159 caseI_KI_Index = 0;
160 caseD_KD_Index = 0;
161 caseF_KF_Index = 0;
162 caseJ_KJ_Index = 0;
163 casec_RS_Index = 0;
164 caseet_RS_Index = 0;
165 caseec_RU_Index = 0;
166 cases_RU_Index = 0;
167 casearray_N_Index = 0;
168 nesttype_RS_Index = 0;
169 nestpair_N_Index = 0;
170 nestname_RU_Iterator = Arrays.asList(nestname_RU).iterator();
171 if (type.equals("RVA") || type.equals("RIA")) {
172 for (int i = 0; i < anno_N.length; i++) {
173 attributes.add(getAttribute(anno_N[i], type_RS[i], pair_N[i], name_RU_Iterator));
174 }
175 } else if (type.equals("RVPA") || type.equals("RIPA")) {
176 anno_N_Index = 0;
177 pair_N_Index = 0;
178 for (final int element : param_NB) {
179 attributes.add(getParameterAttribute(element, name_RU_Iterator));
180 }
181 }
182 } else if (type.equals("AD")) {
183 for (final int element : T) {
184 attributes.add(new AnnotationDefaultAttribute(new ElementValue(element, getNextValue(element))));
185 }
186 }
187 }
188 return attributes;
189 }
190
191 private Object getNextValue(final int t) {
192 switch (t) {
193 case 'B':
194 case 'C':
195 case 'I':
196 case 'S':
197 case 'Z':
198 return caseI_KI[caseI_KI_Index++];
199 case 'D':
200 return caseD_KD[caseD_KD_Index++];
201 case 'F':
202 return caseF_KF[caseF_KF_Index++];
203 case 'J':
204 return caseJ_KJ[caseJ_KJ_Index++];
205 case 'c':
206 return casec_RS[casec_RS_Index++];
207 case 'e':
208
209
210 final String enumString = caseet_RS[caseet_RS_Index++] + ":" + caseec_RU[caseec_RU_Index++];
211 return cpBands.cpNameAndTypeValue(enumString);
212 case 's':
213 return cases_RU[cases_RU_Index++];
214 case '[':
215 final int arraySize = casearray_N[casearray_N_Index++];
216 final ElementValue[] nestedArray = new ElementValue[arraySize];
217 for (int i = 0; i < arraySize; i++) {
218 final int nextT = T[T_index++];
219 nestedArray[i] = new ElementValue(nextT, getNextValue(nextT));
220 }
221 return nestedArray;
222 case '@':
223 final CPUTF8 type = nesttype_RS[nesttype_RS_Index++];
224 final int numPairs = nestpair_N[nestpair_N_Index++];
225
226 return getAnnotation(type, numPairs, nestname_RU_Iterator);
227 }
228 return null;
229 }
230
231 private Attribute getParameterAttribute(final int numParameters, final Iterator<CPUTF8> namesIterator) {
232 final ParameterAnnotation[] parameterAnnotations = new ParameterAnnotation[numParameters];
233 for (int i = 0; i < numParameters; i++) {
234 final int numAnnotations = anno_N[anno_N_Index++];
235 final int[] pairCounts = pair_N[pair_N_Index++];
236 final Annotation[] annotations = new Annotation[numAnnotations];
237 Arrays.setAll(annotations, j -> getAnnotation(type_RS[anno_N_Index - 1][j], pairCounts[j], namesIterator));
238 parameterAnnotations[i] = new ParameterAnnotation(annotations);
239 }
240 return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type.equals("RVPA") ? rvpaUTF8 : ripaUTF8, parameterAnnotations);
241 }
242
243 }