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 com.android.mkstubs; 18 19import com.android.mkstubs.Main.Logger; 20import com.android.mkstubs.sourcer.ClassSourcer; 21import com.android.mkstubs.sourcer.Output; 22 23import org.objectweb.asm.ClassReader; 24import org.objectweb.asm.ClassVisitor; 25 26import java.io.File; 27import java.io.FileWriter; 28import java.io.IOException; 29import java.io.Writer; 30import java.util.Map; 31import 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 */ 40class SourceGenerator { 41 42 private Logger mLog; 43 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 */ 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 FileWriter fw = null; 62 try { 63 fw = createWriter(baseDir, name); 64 visitClassSource(fw, cr, filter); 65 } finally { 66 fw.close(); 67 } 68 } 69 } 70 71 FileWriter createWriter(File baseDir, String name) throws IOException { 72 File f = new File(baseDir, name); 73 f.getParentFile().mkdirs(); 74 75 mLog.debug("Writing " + f.getPath()); 76 77 return new FileWriter(f); 78 } 79 80 /** 81 * Utility method that converts a fully qualified java name into a JAR entry path 82 * e.g. for the input "android.view.View" it returns "android/view/View.java" 83 */ 84 String classNameToJavaPath(String className) { 85 return className.replace('.', '/').concat(".java"); 86 } 87 88 /** 89 * Generate a source equivalent to the stubbed version of the class reader, 90 * minus all exclusions 91 */ 92 void visitClassSource(Writer fw, ClassReader cr, Filter filter) { 93 mLog.debug("Dump " + cr.getClassName()); 94 95 ClassVisitor javaWriter = new ClassSourcer(new Output(fw)); 96 ClassVisitor classFilter = new FilterClassAdapter(javaWriter, filter, mLog); 97 cr.accept(classFilter, 0 /*flags*/); 98 } 99 100} 101