MetadataBandGroup.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.compress.harmony.unpack200;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationDefaultAttribute;
- import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
- import org.apache.commons.compress.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
- import org.apache.commons.compress.harmony.unpack200.bytecode.Attribute;
- import org.apache.commons.compress.harmony.unpack200.bytecode.CPDouble;
- import org.apache.commons.compress.harmony.unpack200.bytecode.CPFloat;
- import org.apache.commons.compress.harmony.unpack200.bytecode.CPInteger;
- import org.apache.commons.compress.harmony.unpack200.bytecode.CPLong;
- import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
- import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
- import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
- import org.apache.commons.compress.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
- /**
- * A group of metadata bands, such as class_RVA_bands, method_AD_bands etc.
- */
- public class MetadataBandGroup {
- private static CPUTF8 rvaUTF8;
- private static CPUTF8 riaUTF8;
- private static CPUTF8 rvpaUTF8;
- private static CPUTF8 ripaUTF8;
- public static void setRiaAttributeName(final CPUTF8 cpUTF8Value) {
- riaUTF8 = cpUTF8Value;
- }
- public static void setRipaAttributeName(final CPUTF8 cpUTF8Value) {
- ripaUTF8 = cpUTF8Value;
- }
- public static void setRvaAttributeName(final CPUTF8 cpUTF8Value) {
- rvaUTF8 = cpUTF8Value;
- }
- public static void setRvpaAttributeName(final CPUTF8 cpUTF8Value) {
- rvpaUTF8 = cpUTF8Value;
- }
- private final String type;
- private final CpBands cpBands;
- private List<Attribute> attributes;
- public int[] param_NB;
- public int[] anno_N;
- public CPUTF8[][] type_RS;
- public int[][] pair_N;
- public CPUTF8[] name_RU;
- public int[] T;
- public CPInteger[] caseI_KI;
- public CPDouble[] caseD_KD;
- public CPFloat[] caseF_KF;
- public CPLong[] caseJ_KJ;
- public CPUTF8[] casec_RS;
- public String[] caseet_RS;
- public String[] caseec_RU;
- public CPUTF8[] cases_RU;
- public int[] casearray_N;
- public CPUTF8[] nesttype_RS;
- public int[] nestpair_N;
- public CPUTF8[] nestname_RU;
- private int caseI_KI_Index;
- private int caseD_KD_Index;
- private int caseF_KF_Index;
- private int caseJ_KJ_Index;
- private int casec_RS_Index;
- private int caseet_RS_Index;
- private int caseec_RU_Index;
- private int cases_RU_Index;
- private int casearray_N_Index;
- private int T_index;
- private int nesttype_RS_Index;
- private int nestpair_N_Index;
- private Iterator<CPUTF8> nestname_RU_Iterator;
- private int anno_N_Index;
- private int pair_N_Index;
- public MetadataBandGroup(final String type, final CpBands cpBands) {
- this.type = type;
- this.cpBands = cpBands;
- }
- private Annotation getAnnotation(final CPUTF8 type, final int pairCount, final Iterator<CPUTF8> namesIterator) {
- final CPUTF8[] elementNames = new CPUTF8[pairCount];
- final ElementValue[] elementValues = new ElementValue[pairCount];
- for (int j = 0; j < elementNames.length; j++) {
- elementNames[j] = namesIterator.next();
- final int t = T[T_index++];
- elementValues[j] = new ElementValue(t, getNextValue(t));
- }
- return new Annotation(pairCount, type, elementNames, elementValues);
- }
- private Attribute getAttribute(final int numAnnotations, final CPUTF8[] types, final int[] pairCounts, final Iterator<CPUTF8> namesIterator) {
- final Annotation[] annotations = new Annotation[numAnnotations];
- Arrays.setAll(annotations, i -> getAnnotation(types[i], pairCounts[i], namesIterator));
- return new RuntimeVisibleorInvisibleAnnotationsAttribute(type.equals("RVA") ? rvaUTF8 : riaUTF8, annotations);
- }
- public List<Attribute> getAttributes() {
- // TODO: Optimize iterators!
- if (attributes == null) {
- attributes = new ArrayList<>();
- if (name_RU != null) {
- final Iterator<CPUTF8> name_RU_Iterator = Arrays.asList(name_RU).iterator();
- if (!type.equals("AD")) {
- T_index = 0;
- }
- caseI_KI_Index = 0;
- caseD_KD_Index = 0;
- caseF_KF_Index = 0;
- caseJ_KJ_Index = 0;
- casec_RS_Index = 0;
- caseet_RS_Index = 0;
- caseec_RU_Index = 0;
- cases_RU_Index = 0;
- casearray_N_Index = 0;
- nesttype_RS_Index = 0;
- nestpair_N_Index = 0;
- nestname_RU_Iterator = Arrays.asList(nestname_RU).iterator();
- if (type.equals("RVA") || type.equals("RIA")) {
- for (int i = 0; i < anno_N.length; i++) {
- attributes.add(getAttribute(anno_N[i], type_RS[i], pair_N[i], name_RU_Iterator));
- }
- } else if (type.equals("RVPA") || type.equals("RIPA")) {
- anno_N_Index = 0;
- pair_N_Index = 0;
- for (final int element : param_NB) {
- attributes.add(getParameterAttribute(element, name_RU_Iterator));
- }
- }
- } else if (type.equals("AD")) {
- for (final int element : T) {
- attributes.add(new AnnotationDefaultAttribute(new ElementValue(element, getNextValue(element))));
- }
- }
- }
- return attributes;
- }
- private Object getNextValue(final int t) {
- switch (t) {
- case 'B':
- case 'C':
- case 'I':
- case 'S':
- case 'Z':
- return caseI_KI[caseI_KI_Index++];
- case 'D':
- return caseD_KD[caseD_KD_Index++];
- case 'F':
- return caseF_KF[caseF_KF_Index++];
- case 'J':
- return caseJ_KJ[caseJ_KJ_Index++];
- case 'c':
- return casec_RS[casec_RS_Index++];
- case 'e':
- // TODO: check this - it may not work if the first string already
- // has a colon in it
- final String enumString = caseet_RS[caseet_RS_Index++] + ":" + caseec_RU[caseec_RU_Index++];
- return cpBands.cpNameAndTypeValue(enumString);
- case 's':
- return cases_RU[cases_RU_Index++];
- case '[':
- final int arraySize = casearray_N[casearray_N_Index++];
- final ElementValue[] nestedArray = new ElementValue[arraySize];
- for (int i = 0; i < arraySize; i++) {
- final int nextT = T[T_index++];
- nestedArray[i] = new ElementValue(nextT, getNextValue(nextT));
- }
- return nestedArray;
- case '@':
- final CPUTF8 type = nesttype_RS[nesttype_RS_Index++];
- final int numPairs = nestpair_N[nestpair_N_Index++];
- return getAnnotation(type, numPairs, nestname_RU_Iterator);
- }
- return null;
- }
- private Attribute getParameterAttribute(final int numParameters, final Iterator<CPUTF8> namesIterator) {
- final ParameterAnnotation[] parameterAnnotations = new ParameterAnnotation[numParameters];
- for (int i = 0; i < numParameters; i++) {
- final int numAnnotations = anno_N[anno_N_Index++];
- final int[] pairCounts = pair_N[pair_N_Index++];
- final Annotation[] annotations = new Annotation[numAnnotations];
- Arrays.setAll(annotations, j -> getAnnotation(type_RS[anno_N_Index - 1][j], pairCounts[j], namesIterator));
- parameterAnnotations[i] = new ParameterAnnotation(annotations);
- }
- return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type.equals("RVPA") ? rvpaUTF8 : ripaUTF8, parameterAnnotations);
- }
- }