19cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll/* 29cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * Copyright (C) 2009 The Android Open Source Project 39cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * 49cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * Licensed under the Apache License, Version 2.0 (the "License"); 59cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * you may not use this file except in compliance with the License. 69cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * You may obtain a copy of the License at 79cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * 89cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * http://www.apache.org/licenses/LICENSE-2.0 99cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * 109cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * Unless required by applicable law or agreed to in writing, software 119cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * distributed under the License is distributed on an "AS IS" BASIS, 129cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * See the License for the specific language governing permissions and 149cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * limitations under the License. 159cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll */ 169cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 179cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollpackage com.android.mkstubs; 189cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 198252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphaelimport com.android.mkstubs.Main.Logger; 208252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael 219cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport org.objectweb.asm.ClassReader; 229cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 239cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.io.IOException; 249cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.Enumeration; 259cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.Iterator; 269cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.Map; 279cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.Set; 289cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.TreeMap; 299cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.zip.ZipEntry; 309cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollimport java.util.zip.ZipFile; 319cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 329cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll/** 33adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * Analyzes an input Jar to get all the relevant classes according to the given filter. 34adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * <p/> 35adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * This is mostly a helper extracted for convenience. Callers will want to use 36adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * {@link #parseInputJar(String)} followed by {@link #filter(Map, Filter)}. 379cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll */ 389cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Mollclass AsmAnalyzer { 399cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 409cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll /** 419cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * Parses a JAR file and returns a list of all classes founds using a map 429cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * class name => ASM ClassReader. Class names are in the form "android.view.View". 439cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll */ 449cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll Map<String,ClassReader> parseInputJar(String inputJarPath) throws IOException { 459cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); 469cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 479cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll ZipFile zip = new ZipFile(inputJarPath); 489cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll Enumeration<? extends ZipEntry> entries = zip.entries(); 499cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll ZipEntry entry; 509cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll while (entries.hasMoreElements()) { 519cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll entry = entries.nextElement(); 529cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll if (entry.getName().endsWith(".class")) { 539cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll ClassReader cr = new ClassReader(zip.getInputStream(entry)); 549cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll String className = classReaderToAsmName(cr); 559cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll classes.put(className, cr); 569cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 579cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 588252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael 599cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll return classes; 609cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 619cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 629cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll /** 639cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * Utility that returns the fully qualified ASM class name for a ClassReader. 649cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll * E.g. it returns something like android/view/View. 659cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll */ 669cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll static String classReaderToAsmName(ClassReader classReader) { 679cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll if (classReader == null) { 689cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll return null; 699cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } else { 709cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll return classReader.getClassName(); 719cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 729cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 739cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 74adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll /** 75adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * Filters the set of classes. Removes all classes that should not be included in the 76adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * filter or that should be excluded. This modifies the map in-place. 778252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael * 78adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * @param classes The in-out map of classes to examine and filter. The map is filtered 79adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * in-place. 80adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll * @param filter A filter describing which classes to include and which ones to exclude. 818252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael * @param log 82adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll */ 838252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael void filter(Map<String, ClassReader> classes, Filter filter, Logger log) { 849cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 859cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll Set<String> keys = classes.keySet(); 869cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll for(Iterator<String> it = keys.iterator(); it.hasNext(); ) { 879cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll String key = it.next(); 889cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll 89adf4543e57086070c95b3ef439dbb6679b0bd562Raphael Moll // TODO: We *could* filter out all private classes here: classes.get(key).getAccess(). 908252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael 919cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll // remove if we don't keep it 92995b5ac934a7b584fecfa055d422fdba93aef812Raphael Moll if (!filter.accept(key)) { 938252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael log.debug("- Remove class " + key); 949cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll it.remove(); 959cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 969cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 979cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll } 988252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael 999cdcde3017e17e1154341e697f855dd15d5d8a47Raphael Moll} 100