Home | History | Annotate | Download | only in mkstubs
      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 
     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             try (FileWriter fw = createWriter(baseDir, name)) {
     62                 visitClassSource(fw, cr, filter);
     63             }
     64         }
     65     }
     66 
     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      */
     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      */
     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