AnnotationDirectoryItem.java revision fa07a1972e3cff56d5615c18a8797ff58fc9f739
1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2009 Ben Gruver 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.dexlib; 30 31import java.util.ArrayList; 32import java.util.Collections; 33import java.util.List; 34 35public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryItem> { 36 private final ArrayList<FieldAnnotation> fieldAnnotationList = new ArrayList<FieldAnnotation>(); 37 private final ArrayList<MethodAnnotation> methodAnnotationList = new ArrayList<MethodAnnotation>(); 38 private final ArrayList<ParameterAnnotation> parameterAnnotationList = new ArrayList<ParameterAnnotation>(); 39 40 private final OffsettedItemReference<AnnotationSetItem> classAnnotationsReferenceField; 41 private final ListSizeField annotatedFieldsCountField; 42 private final ListSizeField annotatedMethodsCountField; 43 private final ListSizeField annotatedParametersCountField; 44 private final FieldListField<FieldAnnotation> fieldAnnotationListField; 45 private final FieldListField<MethodAnnotation> methodAnnotationListField; 46 private final FieldListField<ParameterAnnotation> parameterAnnotationListField; 47 48 public AnnotationDirectoryItem(final DexFile dexFile, int offset) { 49 super(offset); 50 51 fields = new Field[] { 52 classAnnotationsReferenceField = new OffsettedItemReference<AnnotationSetItem>( 53 dexFile.AnnotationSetsSection, new IntegerField(null), "class_annotations_off"), 54 annotatedFieldsCountField = new ListSizeField(fieldAnnotationList, new IntegerField("fields_size")), 55 annotatedMethodsCountField = new ListSizeField(methodAnnotationList, 56 new IntegerField("annotated_methods_size")), 57 annotatedParametersCountField = new ListSizeField(parameterAnnotationList, 58 new IntegerField("annotated_parameters_size")), 59 fieldAnnotationListField = new FieldListField<FieldAnnotation>(fieldAnnotationList, 60 "field_annotations") { 61 protected FieldAnnotation make() { 62 return new FieldAnnotation(dexFile); 63 } 64 }, 65 methodAnnotationListField = new FieldListField<MethodAnnotation>(methodAnnotationList, 66 "method_annotations") { 67 protected MethodAnnotation make() { 68 return new MethodAnnotation(dexFile); 69 } 70 }, 71 parameterAnnotationListField = new FieldListField<ParameterAnnotation>(parameterAnnotationList, 72 "parameter_annotations") { 73 protected ParameterAnnotation make() { 74 return new ParameterAnnotation(dexFile); 75 } 76 } 77 }; 78 } 79 80 public AnnotationDirectoryItem(final DexFile dexFile, 81 AnnotationSetItem classAnnotations, 82 List<FieldAnnotation> fieldAnnotations, 83 List<MethodAnnotation> methodAnnotations, 84 List<ParameterAnnotation> parameterAnnotations) { 85 this(dexFile, -1); 86 87 classAnnotationsReferenceField.setReference(classAnnotations); 88 89 if (fieldAnnotations != null) { 90 fieldAnnotationList.addAll(fieldAnnotations); 91 } 92 93 if (methodAnnotations != null) { 94 methodAnnotationList.addAll(methodAnnotations); 95 } 96 97 if (parameterAnnotations != null) { 98 parameterAnnotationList.addAll(parameterAnnotations); 99 } 100 } 101 102 public int place(int index, int offset) 103 { 104 Collections.sort(fieldAnnotationList); 105 Collections.sort(methodAnnotationList); 106 Collections.sort(parameterAnnotationList); 107 return super.place(index, offset); 108 } 109 110 protected int getAlignment() { 111 return 4; 112 } 113 114 public ItemType getItemType() { 115 return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM; 116 } 117 118 public String getConciseIdentity() { 119 return "annotation_directory_item @0x" + Integer.toHexString(getOffset()); 120 } 121 122 public AnnotationSetItem getClassAnnotations() { 123 return classAnnotationsReferenceField.getReference(); 124 } 125 126 public List<MethodAnnotation> getMethodAnnotations() { 127 return methodAnnotationList; 128 } 129 130 public static class FieldAnnotation extends CompositeField<FieldAnnotation> 131 implements Comparable<FieldAnnotation> { 132 private final IndexedItemReference<FieldIdItem> fieldReferenceField; 133 private final OffsettedItemReference<AnnotationSetItem> annotationSetReferenceField; 134 135 public FieldAnnotation(DexFile dexFile) { 136 super("field_annotation"); 137 fields = new Field[] { 138 fieldReferenceField = new IndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, 139 new IntegerField(null), "field_idx"), 140 annotationSetReferenceField = new OffsettedItemReference<AnnotationSetItem>( 141 dexFile.AnnotationSetsSection, new IntegerField(null), "annotations_off") 142 }; 143 } 144 145 public FieldAnnotation(DexFile dexFile, FieldIdItem field, AnnotationSetItem annotationSet) { 146 this(dexFile); 147 this.fieldReferenceField.setReference(field); 148 this.annotationSetReferenceField.setReference(annotationSet); 149 } 150 151 public int compareTo(FieldAnnotation o) { 152 return ((Integer) fieldReferenceField.getReference().getIndex()).compareTo( 153 o.fieldReferenceField.getReference().getIndex()); 154 } 155 } 156 157 public static class MethodAnnotation extends CompositeField<MethodAnnotation> 158 implements Comparable<MethodAnnotation> { 159 private final IndexedItemReference<MethodIdItem> method; 160 private final OffsettedItemReference<AnnotationSetItem> annotationSet; 161 162 public MethodAnnotation(DexFile dexFile) { 163 super("method_annotation"); 164 fields = new Field[] { 165 method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, 166 new IntegerField(null), "method_idx"), 167 annotationSet = new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, 168 new IntegerField(null), "annotations_off") 169 }; 170 } 171 172 public MethodAnnotation(DexFile dexFile, MethodIdItem method, AnnotationSetItem annotationSet) { 173 this(dexFile); 174 this.method.setReference(method); 175 this.annotationSet.setReference(annotationSet); 176 } 177 178 public int compareTo(MethodAnnotation o) { 179 return ((Integer)method.getReference().getIndex()).compareTo(o.method.getReference().getIndex()); 180 } 181 182 public MethodIdItem getMethod() { 183 return method.getReference(); 184 } 185 186 public AnnotationSetItem getAnnotationSet() { 187 return annotationSet.getReference(); 188 } 189 } 190 191 public static class ParameterAnnotation extends CompositeField<ParameterAnnotation> 192 implements Comparable<ParameterAnnotation> { 193 private final IndexedItemReference<MethodIdItem> method; 194 private final OffsettedItemReference<AnnotationSetRefList> parameterAnnotations; 195 196 public ParameterAnnotation(DexFile dexFile) { 197 super("parameter_annotation"); 198 fields = new Field[] { 199 method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, 200 new IntegerField(null), "method_idx"), 201 parameterAnnotations = new OffsettedItemReference<AnnotationSetRefList>( 202 dexFile.AnnotationSetRefListsSection, new IntegerField(null), "annotations_off") 203 }; 204 } 205 206 public ParameterAnnotation(DexFile dexFile, MethodIdItem method, AnnotationSetRefList parameterAnnotations) { 207 this(dexFile); 208 this.method.setReference(method); 209 this.parameterAnnotations.setReference(parameterAnnotations); 210 } 211 212 public int compareTo(ParameterAnnotation o) { 213 return ((Integer)method.getReference().getIndex()).compareTo(o.method.getReference().getIndex()); 214 } 215 } 216} 217