ClassDefinition.java revision b6547e8fd56242dde90275d9b0ba6f3639083a61
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.baksmali.Adaptors; 30 31import org.jf.dexlib.EncodedValue.EncodedValue; 32import org.jf.dexlib.*; 33import org.jf.dexlib.util.AccessFlags; 34 35import java.util.*; 36 37public class ClassDefinition { 38 private ClassDefItem classDefItem; 39 private ClassDataItem classDataItem; 40 41 private HashMap<Integer, AnnotationSetItem> methodAnnotations = new HashMap<Integer, AnnotationSetItem>(); 42 private HashMap<Integer, AnnotationSetItem> fieldAnnotations = new HashMap<Integer, AnnotationSetItem>(); 43 44 public ClassDefinition(ClassDefItem classDefItem) { 45 this.classDefItem = classDefItem; 46 this.classDataItem = classDefItem.getClassData(); 47 buildAnnotationMaps(); 48 } 49 50 private void buildAnnotationMaps() { 51 AnnotationDirectoryItem annotationDirectory = classDefItem.getAnnotationDirectory(); 52 if (annotationDirectory == null) { 53 return; 54 } 55 56 List<AnnotationDirectoryItem.MethodAnnotation> methodAnnotationList = annotationDirectory.getMethodAnnotations(); 57 if (methodAnnotations != null) { 58 for (AnnotationDirectoryItem.MethodAnnotation methodAnnotation: methodAnnotationList) { 59 methodAnnotations.put(methodAnnotation.getMethod().getIndex(), methodAnnotation.getAnnotationSet()); 60 } 61 } 62 63 List<AnnotationDirectoryItem.FieldAnnotation> fieldAnnotationList = annotationDirectory.getFieldAnnotations(); 64 if (fieldAnnotations != null) { 65 for (AnnotationDirectoryItem.FieldAnnotation fieldAnnotation: fieldAnnotationList) { 66 fieldAnnotations.put(fieldAnnotation.getField().getIndex(), fieldAnnotation.getAnnotationSet()); 67 } 68 } 69 } 70 71 public List<String> getAccessFlags() { 72 List<String> accessFlags = new ArrayList<String>(); 73 74 for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForClass(classDefItem.getAccessFlags())) { 75 accessFlags.add(accessFlag.toString()); 76 } 77 78 return accessFlags; 79 } 80 81 public String getClassType() { 82 return classDefItem.getClassType().getTypeDescriptor(); 83 } 84 85 public String getSuperType() { 86 return classDefItem.getSuperclass().getTypeDescriptor(); 87 } 88 89 public String getSourceFile() { 90 return classDefItem.getSourceFile(); 91 } 92 93 public List<String> getInterfaces() { 94 List<String> interfaces = new ArrayList<String>(); 95 96 List<TypeIdItem> interfaceList = classDefItem.getInterfaces(); 97 98 if (interfaceList != null) { 99 for (TypeIdItem typeIdItem: interfaceList) { 100 interfaces.add(typeIdItem.getTypeDescriptor()); 101 } 102 } 103 104 return interfaces; 105 } 106 107 public List<FieldDefinition> getStaticFields() { 108 List<FieldDefinition> staticFields = new ArrayList<FieldDefinition>(); 109 110 if (classDataItem != null) { 111 112 EncodedArrayItem encodedStaticInitializers = classDefItem.getStaticInitializers(); 113 114 List<EncodedValue> staticInitializers; 115 if (encodedStaticInitializers != null) { 116 staticInitializers = encodedStaticInitializers.getEncodedArray().getValues(); 117 } else { 118 staticInitializers = new ArrayList<EncodedValue>(); 119 } 120 121 int i=0; 122 for (ClassDataItem.EncodedField field: classDataItem.getStaticFields()) { 123 EncodedValue encodedValue = null; 124 if (i < staticInitializers.size()) { 125 encodedValue = staticInitializers.get(i); 126 } 127 AnnotationSetItem annotationSet = fieldAnnotations.get(field.getField().getIndex()); 128 staticFields.add(new FieldDefinition(field, encodedValue, annotationSet)); 129 i++; 130 } 131 } 132 return staticFields; 133 } 134 135 public List<FieldDefinition> getInstanceFields() { 136 List<FieldDefinition> instanceFields = new ArrayList<FieldDefinition>(); 137 138 if (classDataItem != null) { 139 for (ClassDataItem.EncodedField field: classDataItem.getInstanceFields()) { 140 AnnotationSetItem annotationSet = fieldAnnotations.get(field.getField().getIndex()); 141 instanceFields.add(new FieldDefinition(field, annotationSet)); 142 } 143 } 144 145 return instanceFields; 146 } 147 148 public List<MethodDefinition> getDirectMethods() { 149 List<MethodDefinition> directMethods = new ArrayList<MethodDefinition>(); 150 151 if (classDataItem != null) { 152 for (ClassDataItem.EncodedMethod method: classDataItem.getDirectMethods()) { 153 AnnotationSetItem annotationSet = methodAnnotations.get(method.getMethod().getIndex()); 154 directMethods.add(new MethodDefinition(method, annotationSet)); 155 } 156 } 157 158 return directMethods; 159 } 160 161 public List<MethodDefinition> getVirtualMethods() { 162 List<MethodDefinition> virtualMethods = new ArrayList<MethodDefinition>(); 163 164 if (classDataItem != null) { 165 for (ClassDataItem.EncodedMethod method: classDataItem.getVirtualMethods()) { 166 AnnotationSetItem annotationSet = methodAnnotations.get(method.getMethod().getIndex()); 167 virtualMethods.add(new MethodDefinition(method, annotationSet)); 168 } 169 } 170 171 return virtualMethods; 172 } 173 174 public List<AnnotationAdaptor> getAnnotations() { 175 AnnotationDirectoryItem annotationDirectory = classDefItem.getAnnotationDirectory(); 176 if (annotationDirectory == null) { 177 return null; 178 } 179 180 AnnotationSetItem annotationSet = annotationDirectory.getClassAnnotations(); 181 if (annotationSet == null) { 182 return null; 183 } 184 185 List<AnnotationAdaptor> annotationAdaptors = new ArrayList<AnnotationAdaptor>(); 186 187 for (AnnotationItem annotationItem: annotationSet.getAnnotationItems()) { 188 annotationAdaptors.add(new AnnotationAdaptor(annotationItem)); 189 } 190 return annotationAdaptors; 191 } 192} 193