• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 package android.signature.cts;
17 
18 import android.signature.cts.JDiffClassDescription.JDiffConstructor;
19 import android.signature.cts.JDiffClassDescription.JDiffField;
20 import android.signature.cts.JDiffClassDescription.JDiffMethod;
21 
22 import java.lang.reflect.Modifier;
23 
24 import org.xmlpull.v1.XmlPullParser;
25 
26 /**
27  * Helper methods and constants used for parsing the current api file.
28  */
29 public class CurrentApi {
30 
CurrentApi()31     private CurrentApi() {}
32 
33     public static final String API_FILE_DIRECTORY = "/data/local/tmp/signature-test";
34 
35     public static final String CURRENT_API_FILE =
36             API_FILE_DIRECTORY + "/current.api";
37     public static final String SYSTEM_CURRENT_API_FILE =
38             API_FILE_DIRECTORY + "/system-current.api";
39     public static final String SYSTEM_REMOVED_API_FILE =
40             API_FILE_DIRECTORY + "/system-removed.api";
41 
42     static final String TAG_ROOT = "api";
43     static final String TAG_PACKAGE = "package";
44     static final String TAG_CLASS = "class";
45     static final String TAG_INTERFACE = "interface";
46     static final String TAG_IMPLEMENTS = "implements";
47     static final String TAG_CONSTRUCTOR = "constructor";
48     static final String TAG_METHOD = "method";
49     static final String TAG_PARAM = "parameter";
50     static final String TAG_EXCEPTION = "exception";
51     static final String TAG_FIELD = "field";
52 
53     private static final String MODIFIER_ABSTRACT = "abstract";
54     private static final String MODIFIER_FINAL = "final";
55     private static final String MODIFIER_NATIVE = "native";
56     private static final String MODIFIER_PRIVATE = "private";
57     private static final String MODIFIER_PROTECTED = "protected";
58     private static final String MODIFIER_PUBLIC = "public";
59     private static final String MODIFIER_STATIC = "static";
60     private static final String MODIFIER_SYNCHRONIZED = "synchronized";
61     private static final String MODIFIER_TRANSIENT = "transient";
62     private static final String MODIFIER_VOLATILE = "volatile";
63     private static final String MODIFIER_VISIBILITY = "visibility";
64 
65     static final String ATTRIBUTE_NAME = "name";
66     private static final String ATTRIBUTE_VALUE = "value";
67     private static final String ATTRIBUTE_EXTENDS = "extends";
68     static final String ATTRIBUTE_TYPE = "type";
69     private static final String ATTRIBUTE_RETURN = "return";
70 
71     /**
72      * Load field information from xml to memory.
73      *
74      * @param className of the class being examined which will be shown in error messages
75      * @param parser The XmlPullParser which carries the xml information.
76      * @return the new field
77      */
loadFieldInfo(String className, XmlPullParser parser)78     static JDiffField loadFieldInfo(String className, XmlPullParser parser) {
79         String fieldName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
80         String fieldType = parser.getAttributeValue(null, ATTRIBUTE_TYPE);
81         int modifier = jdiffModifierToReflectionFormat(className, parser);
82         String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE);
83         return new JDiffField(fieldName, fieldType, modifier, value);
84     }
85 
86     /**
87      * Load method information from xml to memory.
88      *
89      * @param className of the class being examined which will be shown in error messages
90      * @param parser The XmlPullParser which carries the xml information.
91      * @return the newly loaded method.
92      */
loadMethodInfo(String className, XmlPullParser parser)93     static JDiffMethod loadMethodInfo(String className, XmlPullParser parser) {
94         String methodName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
95         String returnType = parser.getAttributeValue(null, ATTRIBUTE_RETURN);
96         int modifier = jdiffModifierToReflectionFormat(className, parser);
97         return new JDiffMethod(methodName, modifier, returnType);
98     }
99 
100     /**
101      * Load constructor information from xml to memory.
102      *
103      * @param parser The XmlPullParser which carries the xml information.
104      * @param currentClass the current class being loaded.
105      * @return the new constructor
106      */
loadConstructorInfo( XmlPullParser parser, JDiffClassDescription currentClass)107     static JDiffConstructor loadConstructorInfo(
108             XmlPullParser parser, JDiffClassDescription currentClass) {
109         String name = currentClass.getClassName();
110         int modifier = jdiffModifierToReflectionFormat(name, parser);
111         return new JDiffConstructor(name, modifier);
112     }
113 
114     /**
115      * Load class or interface information to memory.
116      *
117      * @param parser The XmlPullParser which carries the xml information.
118      * @param isInterface true if the current class is an interface, otherwise is false.
119      * @param pkg the name of the java package this class can be found in.
120      * @return the new class description.
121      */
loadClassInfo( XmlPullParser parser, boolean isInterface, String pkg)122     static JDiffClassDescription loadClassInfo(
123             XmlPullParser parser, boolean isInterface, String pkg) {
124         String className = parser.getAttributeValue(null, ATTRIBUTE_NAME);
125         JDiffClassDescription currentClass = new JDiffClassDescription(pkg, className);
126 
127         currentClass.setModifier(jdiffModifierToReflectionFormat(className, parser));
128         currentClass.setType(isInterface ? JDiffClassDescription.JDiffType.INTERFACE :
129                              JDiffClassDescription.JDiffType.CLASS);
130         currentClass.setExtendsClass(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS));
131         return currentClass;
132     }
133 
134     /**
135      * Convert string modifier to int modifier.
136      *
137      * @param name of the class/method/field being examined which will be shown in error messages
138      * @param key modifier name
139      * @param value modifier value
140      * @return converted modifier value
141      */
modifierDescriptionToReflectedType(String name, String key, String value)142     private static int modifierDescriptionToReflectedType(String name, String key, String value) {
143         if (key.equals(MODIFIER_ABSTRACT)) {
144             return value.equals("true") ? Modifier.ABSTRACT : 0;
145         } else if (key.equals(MODIFIER_FINAL)) {
146             return value.equals("true") ? Modifier.FINAL : 0;
147         } else if (key.equals(MODIFIER_NATIVE)) {
148             return value.equals("true") ? Modifier.NATIVE : 0;
149         } else if (key.equals(MODIFIER_STATIC)) {
150             return value.equals("true") ? Modifier.STATIC : 0;
151         } else if (key.equals(MODIFIER_SYNCHRONIZED)) {
152             return value.equals("true") ? Modifier.SYNCHRONIZED : 0;
153         } else if (key.equals(MODIFIER_TRANSIENT)) {
154             return value.equals("true") ? Modifier.TRANSIENT : 0;
155         } else if (key.equals(MODIFIER_VOLATILE)) {
156             return value.equals("true") ? Modifier.VOLATILE : 0;
157         } else if (key.equals(MODIFIER_VISIBILITY)) {
158             if (value.equals(MODIFIER_PRIVATE)) {
159                 throw new RuntimeException("Private visibility found in API spec: " + name);
160             } else if (value.equals(MODIFIER_PROTECTED)) {
161                 return Modifier.PROTECTED;
162             } else if (value.equals(MODIFIER_PUBLIC)) {
163                 return Modifier.PUBLIC;
164             } else if ("".equals(value)) {
165                 // If the visibility is "", it means it has no modifier.
166                 // which is package private. We should return 0 for this modifier.
167                 return 0;
168             } else {
169                 throw new RuntimeException("Unknown modifier found in API spec: " + value);
170             }
171         }
172         return 0;
173     }
174 
175     /**
176      * Transfer string modifier to int one.
177      *
178      * @param name of the class/method/field being examined which will be shown in error messages
179      * @param parser XML resource parser
180      * @return converted modifier
181      */
jdiffModifierToReflectionFormat(String name, XmlPullParser parser)182     private static int jdiffModifierToReflectionFormat(String name, XmlPullParser parser){
183         int modifier = 0;
184         for (int i = 0;i < parser.getAttributeCount();i++) {
185             modifier |= modifierDescriptionToReflectedType(name, parser.getAttributeName(i),
186                     parser.getAttributeValue(i));
187         }
188         return modifier;
189     }
190 }
191