1 /* 2 * Copyright (C) 2010 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 17 package com.android.cts.apicommon; 18 19 import java.util.Collection; 20 import java.util.Collections; 21 import java.util.Iterator; 22 import java.util.Map; 23 import java.util.Map.Entry; 24 import java.util.concurrent.ConcurrentHashMap; 25 26 /** Representation of a package in the API containing classes. */ 27 public class ApiPackage implements HasCoverage { 28 29 private final String mName; 30 31 private final Map<String, ApiClass> mApiClassMap = new ConcurrentHashMap<>(); 32 ApiPackage(String name)33 public ApiPackage(String name) { 34 mName = name; 35 } 36 37 @Override getName()38 public String getName() { 39 return mName; 40 } 41 addClass(ApiClass apiClass)42 public void addClass(ApiClass apiClass) { 43 mApiClassMap.put(apiClass.getName(), apiClass); 44 } 45 getClass(String name)46 public ApiClass getClass(String name) { 47 return name == null ? null : mApiClassMap.get(name); 48 } 49 getClasses()50 public Collection<ApiClass> getClasses() { 51 return Collections.unmodifiableCollection(mApiClassMap.values()); 52 } 53 getNumCoveredMethods()54 public int getNumCoveredMethods() { 55 int covered = 0; 56 for (ApiClass apiClass : mApiClassMap.values()) { 57 covered += apiClass.getNumCoveredMethods(); 58 } 59 return covered; 60 } 61 getTotalMethods()62 public int getTotalMethods() { 63 int total = 0; 64 for (ApiClass apiClass : mApiClassMap.values()) { 65 total += apiClass.getTotalMethods(); 66 } 67 return total; 68 } 69 70 @Override getCoveragePercentage()71 public float getCoveragePercentage() { 72 return (float) getNumCoveredMethods() / getTotalMethods() * 100; 73 } 74 75 @Override getMemberSize()76 public int getMemberSize() { 77 return getTotalMethods(); 78 } 79 80 /** Iterate through all classes and add superclass. */ resolveSuperClasses(Map<String, ApiPackage> packageMap)81 public void resolveSuperClasses(Map<String, ApiPackage> packageMap) { 82 Iterator<Entry<String, ApiClass>> it = mApiClassMap.entrySet().iterator(); 83 while (it.hasNext()) { 84 Map.Entry<String, ApiClass> entry = it.next(); 85 ApiClass apiClass = entry.getValue(); 86 if (apiClass.getSuperClassName() != null) { 87 // Add the super class 88 String superClassName = apiClass.getSuperClassName(); 89 ApiClass superClass = findClass(packageMap, superClassName); 90 apiClass.setSuperClass(superClass); 91 } 92 for (String interfaceName : apiClass.getInterfaceNames()) { 93 // Add the interface 94 ApiClass apiInterface = findClass(packageMap, interfaceName); 95 apiClass.resolveInterface(interfaceName, apiInterface); 96 } 97 } 98 } 99 100 /** Find a class that matches the fully qualified class name. */ findClass(Map<String, ApiPackage> packageMap, String fullClassName)101 private ApiClass findClass(Map<String, ApiPackage> packageMap, String fullClassName) { 102 // Split the fully qualified class name into package and class name. 103 int delimiterIndex = fullClassName.lastIndexOf('.'); 104 while (delimiterIndex > 0) { 105 String packageName = fullClassName.substring(0, delimiterIndex); 106 String className = fullClassName.substring(delimiterIndex + 1); 107 if (packageMap.containsKey(packageName)) { 108 ApiPackage apiPackage = packageMap.get(packageName); 109 ApiClass apiClass = apiPackage.getClass(className); 110 if (apiClass != null) { 111 // api class found 112 return apiClass; 113 } 114 } 115 delimiterIndex = fullClassName.lastIndexOf('.', delimiterIndex - 1); 116 } 117 return null; 118 } 119 } 120