Main.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.tools.layoutlib.create; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Main { 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void main(String[] args) { 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log log = new Log(); 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<String> osJarPath = new ArrayList<String>(); 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] osDestJar = { null }; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!processArgs(log, args, osJarPath, osDestJar)) { 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error("Usage: layoutlib_create [-v] output.jar input.jar ..."); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(1); 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.info("Output: %1$s", osDestJar[0]); 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String path : osJarPath) { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.info("Input : %1$s", path); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AsmGenerator agen = new AsmGenerator(log, osDestJar[0], 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Class<?>[] { // classes to inject in the final JAR 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OverrideMethod.class, 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MethodListener.class, 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MethodAdapter.class 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { // methods to force override 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.view.View#isInEditMode", 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.content.res.Resources$Theme#obtainStyledAttributes", 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { // classes to rename (so that we can replace them in layoutlib) 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // original-platform-class-name ======> renamed-class-name 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Matrix", "android.graphics._Original_Matrix", 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint", "android.graphics._Original_Paint", 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Typeface", "android.graphics._Original_Typeface", 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Bitmap", "android.graphics._Original_Bitmap", 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Path", "android.graphics._Original_Path", 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.PorterDuffXfermode", "android.graphics._Original_PorterDuffXfermode", 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Shader", "android.graphics._Original_Shader", 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.LinearGradient", "android.graphics._Original_LinearGradient", 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.BitmapShader", "android.graphics._Original_BitmapShader", 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.ComposeShader", "android.graphics._Original_ComposeShader", 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.RadialGradient", "android.graphics._Original_RadialGradient", 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.SweepGradient", "android.graphics._Original_SweepGradient", 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.util.FloatMath", "android.util._Original_FloatMath", 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.view.SurfaceView", "android.view._Original_SurfaceView", 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { // methods deleted from their return type. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint", // class to delete method from 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$Align", // list of type identifying methods to delete 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$Style", 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$Join", 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$Cap", 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$FontMetrics", 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.Paint$FontMetricsInt", 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen, 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { "android.view.View" }, // derived from 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { // include classes 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.*", // for android.R 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.util.*", 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com.android.internal.util.*", 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.view.*", 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.widget.*", 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com.android.internal.widget.*", 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.text.**", 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.*", 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.graphics.drawable.*", 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.content.*", 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.content.res.*", 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "org.apache.harmony.xml.*", 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com.android.internal.R**", 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.pim.*", // for datepicker 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.os.*", // for android.os.Handler 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project aa.analyze(); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project agen.generate(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Throw an error if any class failed to get renamed by the generator 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // IMPORTANT: if you're building the platform and you get this error message, 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it means the renameClasses[] array in AsmGenerator needs to be updated: some 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // class should have been renamed but it was not found in the input JAR files. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Set<String> notRenamed = agen.getClassesNotRenamed(); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notRenamed.size() > 0) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (80-column guide below for error formatting) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error( 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ERROR when running layoutlib_create: the following classes are referenced\n" + 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "by tools/layoutlib/create but were not actually found in the input JAR files.\n" + 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "This may be due to some platform classes having been renamed."); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String fqcn : notRenamed) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error("- Class not found: %s", fqcn.replace('/', '.')); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String path : osJarPath) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.info("- Input JAR : %1$s", path); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(1); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(0); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.exception(e, "Failed to load jar"); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (LogAbortException e) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.error(log); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(1); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if args where properly parsed. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns false if program should exit with command-line usage. 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p/> 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: the String[0] is an output parameter wrapped in an array, since there is no 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "out" parameter support. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean processArgs(Log log, String[] args, 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<String> osJarPath, String[] osDestJar) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < args.length; i++) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String s = args[i]; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s.equals("-v")) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.setVerbose(true); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!s.startsWith("-")) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (osDestJar[0] == null) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project osDestJar[0] = s; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project osJarPath.add(s); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error("Unknow argument: %s", s); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (osJarPath.isEmpty()) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error("Missing parameter: path to input jar"); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (osDestJar[0] == null) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log.error("Missing parameter: path to output jar"); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 175