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