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 17 package com.android.mkstubs; 18 19 import com.android.mkstubs.Main.Logger; 20 import com.android.mkstubs.sourcer.ClassSourcer; 21 import com.android.mkstubs.sourcer.Output; 22 23 import org.objectweb.asm.ClassReader; 24 import org.objectweb.asm.ClassVisitor; 25 26 import java.io.File; 27 import java.io.FileWriter; 28 import java.io.IOException; 29 import java.io.Writer; 30 import java.util.Map; 31 import java.util.Map.Entry; 32 33 /** 34 * Given a set of already filtered classes, this filters out all private members and then 35 * generates the Java source for the remaining classes. 36 * <p/> 37 * This is an helper extracted for convenience. Callers just need to use 38 * {@link #generateSource(File, Map, Filter)}. 39 */ 40 class SourceGenerator { 41 42 private Logger mLog; 43 SourceGenerator(Logger log)44 public SourceGenerator(Logger log) { 45 mLog = log; 46 } 47 48 /** 49 * Generate source for the stubbed classes, mostly for debug purposes. 50 * @throws IOException 51 */ generateSource(File baseDir, Map<String, ClassReader> classes, Filter filter)52 public void generateSource(File baseDir, 53 Map<String, ClassReader> classes, 54 Filter filter) throws IOException { 55 56 for (Entry<String, ClassReader> entry : classes.entrySet()) { 57 ClassReader cr = entry.getValue(); 58 59 String name = classNameToJavaPath(cr.getClassName()); 60 61 try (FileWriter fw = createWriter(baseDir, name)) { 62 visitClassSource(fw, cr, filter); 63 } 64 } 65 } 66 createWriter(File baseDir, String name)67 FileWriter createWriter(File baseDir, String name) throws IOException { 68 File f = new File(baseDir, name); 69 f.getParentFile().mkdirs(); 70 71 mLog.debug("Writing " + f.getPath()); 72 73 return new FileWriter(f); 74 } 75 76 /** 77 * Utility method that converts a fully qualified java name into a JAR entry path 78 * e.g. for the input "android.view.View" it returns "android/view/View.java" 79 */ classNameToJavaPath(String className)80 String classNameToJavaPath(String className) { 81 return className.replace('.', '/').concat(".java"); 82 } 83 84 /** 85 * Generate a source equivalent to the stubbed version of the class reader, 86 * minus all exclusions 87 */ visitClassSource(Writer fw, ClassReader cr, Filter filter)88 void visitClassSource(Writer fw, ClassReader cr, Filter filter) { 89 mLog.debug("Dump " + cr.getClassName()); 90 91 ClassVisitor javaWriter = new ClassSourcer(new Output(fw)); 92 ClassVisitor classFilter = new FilterClassAdapter(javaWriter, filter, mLog); 93 cr.accept(classFilter, 0 /*flags*/); 94 } 95 96 } 97