• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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