Main.java revision 32557b47c5418ec1be949f15be5440701a8c06a6
11297169e0952bcec5786304b29b45017d7074d52Raphael Moll/* 21297169e0952bcec5786304b29b45017d7074d52Raphael Moll * Copyright (C) 2009 The Android Open Source Project 31297169e0952bcec5786304b29b45017d7074d52Raphael Moll * 41297169e0952bcec5786304b29b45017d7074d52Raphael Moll * Licensed under the Apache License, Version 2.0 (the "License"); 51297169e0952bcec5786304b29b45017d7074d52Raphael Moll * you may not use this file except in compliance with the License. 61297169e0952bcec5786304b29b45017d7074d52Raphael Moll * You may obtain a copy of the License at 71297169e0952bcec5786304b29b45017d7074d52Raphael Moll * 81297169e0952bcec5786304b29b45017d7074d52Raphael Moll * http://www.apache.org/licenses/LICENSE-2.0 91297169e0952bcec5786304b29b45017d7074d52Raphael Moll * 101297169e0952bcec5786304b29b45017d7074d52Raphael Moll * Unless required by applicable law or agreed to in writing, software 111297169e0952bcec5786304b29b45017d7074d52Raphael Moll * distributed under the License is distributed on an "AS IS" BASIS, 121297169e0952bcec5786304b29b45017d7074d52Raphael Moll * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131297169e0952bcec5786304b29b45017d7074d52Raphael Moll * See the License for the specific language governing permissions and 141297169e0952bcec5786304b29b45017d7074d52Raphael Moll * limitations under the License. 151297169e0952bcec5786304b29b45017d7074d52Raphael Moll */ 161297169e0952bcec5786304b29b45017d7074d52Raphael Moll 171297169e0952bcec5786304b29b45017d7074d52Raphael Mollpackage com.android.mkstubs; 181297169e0952bcec5786304b29b45017d7074d52Raphael Moll 191297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport org.objectweb.asm.ClassReader; 201297169e0952bcec5786304b29b45017d7074d52Raphael Moll 211297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport java.io.BufferedReader; 221297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport java.io.File; 231297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport java.io.FileReader; 241297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport java.io.IOException; 251297169e0952bcec5786304b29b45017d7074d52Raphael Mollimport java.util.Map; 261297169e0952bcec5786304b29b45017d7074d52Raphael Moll 271297169e0952bcec5786304b29b45017d7074d52Raphael Moll 281297169e0952bcec5786304b29b45017d7074d52Raphael Moll/** 291297169e0952bcec5786304b29b45017d7074d52Raphael Moll * 301297169e0952bcec5786304b29b45017d7074d52Raphael Moll */ 311297169e0952bcec5786304b29b45017d7074d52Raphael Mollpublic class Main { 321297169e0952bcec5786304b29b45017d7074d52Raphael Moll 331297169e0952bcec5786304b29b45017d7074d52Raphael Moll static class Params { 341297169e0952bcec5786304b29b45017d7074d52Raphael Moll private String mInputJarPath; 351297169e0952bcec5786304b29b45017d7074d52Raphael Moll private String mOutputJarPath; 3632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll private Filter mFilter; 3732557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 381297169e0952bcec5786304b29b45017d7074d52Raphael Moll public Params(String inputJarPath, String outputJarPath) { 391297169e0952bcec5786304b29b45017d7074d52Raphael Moll mInputJarPath = inputJarPath; 401297169e0952bcec5786304b29b45017d7074d52Raphael Moll mOutputJarPath = outputJarPath; 4132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll mFilter = new Filter(); 421297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 431297169e0952bcec5786304b29b45017d7074d52Raphael Moll 441297169e0952bcec5786304b29b45017d7074d52Raphael Moll public String getInputJarPath() { 451297169e0952bcec5786304b29b45017d7074d52Raphael Moll return mInputJarPath; 461297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 471297169e0952bcec5786304b29b45017d7074d52Raphael Moll 481297169e0952bcec5786304b29b45017d7074d52Raphael Moll public String getOutputJarPath() { 491297169e0952bcec5786304b29b45017d7074d52Raphael Moll return mOutputJarPath; 501297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 511297169e0952bcec5786304b29b45017d7074d52Raphael Moll 5232557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll public Filter getFilter() { 5332557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll return mFilter; 541297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 551297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 561297169e0952bcec5786304b29b45017d7074d52Raphael Moll 571297169e0952bcec5786304b29b45017d7074d52Raphael Moll /** 581297169e0952bcec5786304b29b45017d7074d52Raphael Moll * @param args 591297169e0952bcec5786304b29b45017d7074d52Raphael Moll */ 601297169e0952bcec5786304b29b45017d7074d52Raphael Moll public static void main(String[] args) { 611297169e0952bcec5786304b29b45017d7074d52Raphael Moll 621297169e0952bcec5786304b29b45017d7074d52Raphael Moll Main m = new Main(); 631297169e0952bcec5786304b29b45017d7074d52Raphael Moll try { 641297169e0952bcec5786304b29b45017d7074d52Raphael Moll Params p = m.processArgs(args); 651297169e0952bcec5786304b29b45017d7074d52Raphael Moll m.process(p); 661297169e0952bcec5786304b29b45017d7074d52Raphael Moll } catch (IOException e) { 671297169e0952bcec5786304b29b45017d7074d52Raphael Moll e.printStackTrace(); 681297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 691297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 701297169e0952bcec5786304b29b45017d7074d52Raphael Moll 711297169e0952bcec5786304b29b45017d7074d52Raphael Moll private Params processArgs(String[] args) throws IOException { 721297169e0952bcec5786304b29b45017d7074d52Raphael Moll 731297169e0952bcec5786304b29b45017d7074d52Raphael Moll if (args.length < 2) { 741297169e0952bcec5786304b29b45017d7074d52Raphael Moll usage(); 751297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 761297169e0952bcec5786304b29b45017d7074d52Raphael Moll 771297169e0952bcec5786304b29b45017d7074d52Raphael Moll Params p = new Params(args[0], args[1]); 781297169e0952bcec5786304b29b45017d7074d52Raphael Moll 791297169e0952bcec5786304b29b45017d7074d52Raphael Moll for (int i = 2; i < args.length; i++) { 8032557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll addString(p, args[i]); 811297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 821297169e0952bcec5786304b29b45017d7074d52Raphael Moll 831297169e0952bcec5786304b29b45017d7074d52Raphael Moll return p; 841297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 851297169e0952bcec5786304b29b45017d7074d52Raphael Moll 8632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll private void addString(Params p, String s) throws IOException { 8732557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll s = s.trim(); 8832557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 8932557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll if (s.length() < 2) { 9032557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll return; 9132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } 9232557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 9332557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll char mode = s.charAt(0); 9432557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll s = s.substring(1).trim(); 9532557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 9632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll if (mode == '@') { 9732557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll addStringsFromFile(p, s); 9832557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 9932557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } else if (mode == '-') { 10032557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll s = s.replace('.', '/'); // transform FQCN into ASM internal name 10132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll if (s.endsWith("*")) { 10232557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll p.getFilter().getExcludePrefix().add(s.substring(0, s.length() - 1)); 10332557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } else { 10432557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll p.getFilter().getExcludeFull().add(s); 10532557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } 10632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 10732557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } else if (mode == '+') { 10832557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll s = s.replace('.', '/'); // transform FQCN into ASM internal name 10932557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll if (s.endsWith("*")) { 11032557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll p.getFilter().getIncludePrefix().add(s.substring(0, s.length() - 1)); 11132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } else { 11232557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll p.getFilter().getIncludeFull().add(s); 11332557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } 11432557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } 11532557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll } 11632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 1171297169e0952bcec5786304b29b45017d7074d52Raphael Moll private void addStringsFromFile(Params p, String inputFile) 1181297169e0952bcec5786304b29b45017d7074d52Raphael Moll throws IOException { 1191297169e0952bcec5786304b29b45017d7074d52Raphael Moll BufferedReader br = null; 1201297169e0952bcec5786304b29b45017d7074d52Raphael Moll try { 1211297169e0952bcec5786304b29b45017d7074d52Raphael Moll br = new BufferedReader(new FileReader(inputFile)); 1221297169e0952bcec5786304b29b45017d7074d52Raphael Moll String line; 1231297169e0952bcec5786304b29b45017d7074d52Raphael Moll while ((line = br.readLine()) != null) { 12432557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll addString(p, line); 1251297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 1261297169e0952bcec5786304b29b45017d7074d52Raphael Moll } finally { 1271297169e0952bcec5786304b29b45017d7074d52Raphael Moll br.close(); 1281297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 1291297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 1301297169e0952bcec5786304b29b45017d7074d52Raphael Moll 1311297169e0952bcec5786304b29b45017d7074d52Raphael Moll private void usage() { 1321297169e0952bcec5786304b29b45017d7074d52Raphael Moll System.out.println("Usage: mkstub input.jar output.jar [excluded-class @excluded-classes-file ...]"); 1331297169e0952bcec5786304b29b45017d7074d52Raphael Moll 1341297169e0952bcec5786304b29b45017d7074d52Raphael Moll System.out.println("Include syntax:\n" + 1351297169e0952bcec5786304b29b45017d7074d52Raphael Moll "+com.package.* : whole package, with glob\n" + 1361297169e0952bcec5786304b29b45017d7074d52Raphael Moll "+com.package.Class[$Inner] or ...Class*: whole classes with optional glob\n" + 1371297169e0952bcec5786304b29b45017d7074d52Raphael Moll "Inclusion is not supported at method/field level.\n\n"); 1381297169e0952bcec5786304b29b45017d7074d52Raphael Moll 1391297169e0952bcec5786304b29b45017d7074d52Raphael Moll System.out.println("Exclude syntax:\n" + 1401297169e0952bcec5786304b29b45017d7074d52Raphael Moll "-com.package.* : whole package, with glob\n" + 1411297169e0952bcec5786304b29b45017d7074d52Raphael Moll "-com.package.Class[$Inner] or ...Class*: whole classes with optional glob\n" + 1421297169e0952bcec5786304b29b45017d7074d52Raphael Moll "-com.package.Class#method: whole method or field\n" + 1431297169e0952bcec5786304b29b45017d7074d52Raphael Moll "-com.package.Class#method(IILjava/lang/String;)V: specific method with signature.\n\n"); 1441297169e0952bcec5786304b29b45017d7074d52Raphael Moll System.exit(1); 1451297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 1461297169e0952bcec5786304b29b45017d7074d52Raphael Moll 1471297169e0952bcec5786304b29b45017d7074d52Raphael Moll private void process(Params p) throws IOException { 1481297169e0952bcec5786304b29b45017d7074d52Raphael Moll AsmAnalyzer aa = new AsmAnalyzer(); 1491297169e0952bcec5786304b29b45017d7074d52Raphael Moll Map<String, ClassReader> classes = aa.parseInputJar(p.getInputJarPath()); 15032557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 15132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll System.out.println(String.format("Classes loaded: %d", classes.size())); 15232557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 15332557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll aa.filter(classes, p.getFilter()); 15432557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll 15532557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll System.out.println(String.format("Classes filtered: %d", classes.size())); 1561297169e0952bcec5786304b29b45017d7074d52Raphael Moll 1571297169e0952bcec5786304b29b45017d7074d52Raphael Moll // dump as Java source files, mostly for debugging 158323557aaf99f85ec31069e82460b30dfa2abf777Raphael Moll SourceGenerator src_gen = new SourceGenerator(); 159323557aaf99f85ec31069e82460b30dfa2abf777Raphael Moll File dst_src_dir = new File(p.getOutputJarPath() + "_sources"); 1601297169e0952bcec5786304b29b45017d7074d52Raphael Moll dst_src_dir.mkdir(); 16132557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll src_gen.generateSource(dst_src_dir, classes, p.getFilter()); 1621297169e0952bcec5786304b29b45017d7074d52Raphael Moll 163323557aaf99f85ec31069e82460b30dfa2abf777Raphael Moll // dump the stubbed jar 164323557aaf99f85ec31069e82460b30dfa2abf777Raphael Moll StubGenerator stub_gen = new StubGenerator(); 165323557aaf99f85ec31069e82460b30dfa2abf777Raphael Moll File dst_jar = new File(p.getOutputJarPath()); 16632557b47c5418ec1be949f15be5440701a8c06a6Raphael Moll stub_gen.generateStubbedJar(dst_jar, classes, p.getFilter()); 1671297169e0952bcec5786304b29b45017d7074d52Raphael Moll } 1681297169e0952bcec5786304b29b45017d7074d52Raphael Moll} 169