1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package dex.reader;
18
19import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertNotNull;
21import static org.junit.Assert.assertTrue;
22import static org.junit.Assert.fail;
23
24import org.junit.After;
25import org.junit.Before;
26
27import dex.reader.util.JavaSourceToDexUtil;
28import dex.structure.DexAnnotatedElement;
29import dex.structure.DexAnnotation;
30import dex.structure.DexClass;
31import dex.structure.DexField;
32import dex.structure.DexFile;
33import dex.structure.DexMethod;
34import dex.structure.DexParameter;
35import dex.structure.WithModifiers;
36
37import java.io.IOException;
38import java.lang.reflect.Modifier;
39import java.util.Arrays;
40import java.util.LinkedList;
41import java.util.List;
42
43public class DexTestsCommon {
44
45    protected JavaSourceToDexUtil javaToDexUtil;
46
47    @Before
48    public void initializeJavaToDexUtil() {
49        javaToDexUtil = new JavaSourceToDexUtil();
50    }
51
52    @After
53    public void shutdownJavaToDexUtil() {
54        javaToDexUtil = null;
55    }
56
57    public static void assertPublic(WithModifiers withMod) {
58        assertTrue(Modifier.isPublic(withMod.getModifiers()));
59        assertFalse(Modifier.isPrivate(withMod.getModifiers())
60                || Modifier.isProtected(withMod.getModifiers()));
61    }
62
63    public static void assertProtected(WithModifiers withMod) {
64        assertTrue(Modifier.isProtected(withMod.getModifiers()));
65        assertFalse(Modifier.isPrivate(withMod.getModifiers())
66                || Modifier.isPublic(withMod.getModifiers()));
67    }
68
69    public static void assertPrivate(WithModifiers withMod) {
70        assertTrue(Modifier.isPrivate(withMod.getModifiers()));
71        assertFalse(Modifier.isProtected(withMod.getModifiers())
72                || Modifier.isPublic(withMod.getModifiers()));
73    }
74
75    public static void assertDefault(WithModifiers withMod) {
76        assertFalse(Modifier.isPrivate(withMod.getModifiers())
77                || Modifier.isProtected(withMod.getModifiers())
78                || Modifier.isPublic(withMod.getModifiers()));
79    }
80
81    /**
82     * Creates and returns a dex file from the specified file.
83     *
84     * @param fileName the name of the file to read
85     * @return the dex file
86     * @throws IOException if the file is not accessible
87     */
88    protected DexFile prepareDexFile(String fileName) throws IOException{
89        DexFileReader dexReader = new DexFileReader();
90        return  dexReader.read(new DexBuffer(fileName));
91    }
92
93    protected DexClass getClass(DexFile file, String className) {
94        assertNotNull(file);
95        assertNotNull(className);
96        for (DexClass clazz : file.getDefinedClasses()) {
97            if(className.equals(clazz.getName())){
98                return clazz;
99            }
100        }
101        fail("Class: " + className +" not present in file: " + file.getName());
102        throw new IllegalArgumentException("Class: " + className +" not present in file: " + file.getName());
103    }
104
105    protected DexField getField(DexClass clazz, String fieldName) {
106        assertNotNull(clazz);
107        assertNotNull(fieldName);
108        for (DexField field : clazz.getFields()) {
109            if(fieldName.equals(field.getName())){
110                return field;
111            }
112        }
113        fail("Field: " + fieldName +" not present in class: " + clazz.getName());
114        throw new IllegalArgumentException("Field: " + fieldName +" not present in class: " + clazz.getName());
115    }
116
117    protected DexAnnotation getAnnotation(DexAnnotatedElement element, String annotationType) {
118        assertNotNull(element);
119        assertNotNull(annotationType);
120        for (DexAnnotation anno : element.getAnnotations()) {
121            if(annotationType.equals(anno.getTypeName())){
122                return anno;
123            }
124        }
125        fail("Annotation: " + annotationType +" not present in Element.");
126        throw new IllegalArgumentException("Annotation: " + annotationType +" not present in Element.");
127    }
128
129    protected DexMethod getMethod(DexClass clazz, String methodName, String... typeNames) {
130        assertNotNull(clazz);
131        assertNotNull(methodName);
132        List<String> paramTypeNames = Arrays.asList(typeNames);
133        for (DexMethod method : clazz.getMethods()) {
134            List<String> methodsParamTypeNames = getParamTypeNames(method.getParameters());
135            if(methodName.equals(method.getName()) && paramTypeNames.equals(methodsParamTypeNames)){
136                return method;
137            }
138        }
139        fail("Method: " + methodName +" not present in class: " + clazz.getName());
140        throw new IllegalArgumentException("Method: " + methodName +" not present in class: " + clazz.getName());
141    }
142
143    private List<String> getParamTypeNames(List<DexParameter> parameters) {
144        List<String> paramTypeNames = new LinkedList<String>();
145        for (DexParameter parameter : parameters) {
146            paramTypeNames.add(parameter.getTypeName());
147        }
148        return paramTypeNames;
149    }
150
151}
152