1f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project/* 2f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 3f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 4f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * you may not use this file except in compliance with the License. 6f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * You may obtain a copy of the License at 7f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 8f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 10f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * See the License for the specific language governing permissions and 14f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * limitations under the License. 15f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project */ 16f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 17f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectpackage dex.reader.util; 18f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 19f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.io.IOException; 20f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.Arrays; 21f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.Collections; 22f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.HashSet; 23f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.Set; 24f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 25f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.Diagnostic; 26f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.DiagnosticCollector; 27f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.JavaCompiler; 28f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.JavaFileObject; 29f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.StandardJavaFileManager; 30f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.ToolProvider; 31f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport javax.tools.JavaCompiler.CompilationTask; 32f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 33f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport com.android.dx.dex.cf.CfOptions; 34f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport com.android.dx.dex.cf.CfTranslator; 35f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport com.android.dx.dex.file.ClassDefItem; 36f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport com.android.dx.dex.file.DexFile; 37f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 38f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexBuffer; 39f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexFileReader; 40f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 41f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectpublic class JavaSourceToDexUtil { 42f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 43f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public dex.structure.DexFile getFrom(JavaSource source) throws IOException{ 44f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return getAllFrom(Collections.singleton(source)); 45f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 46f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 47f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public dex.structure.DexFile getFrom(JavaSource... source) throws IOException{ 48f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return getAllFrom(new HashSet<JavaSource>(Arrays.asList(source))); 49f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 50f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 51f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public dex.structure.DexFile getAllFrom(Set<JavaSource> sources) throws IOException{ 52f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return getFrom(sources, null); 53f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 54f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 55f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project /** 56f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Converts java source code to a {@link dex.structure.DexFile} loaded by 57f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * {@link DexFileReader}. Converts only classes with the specified name in 58f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * classesToDex or all classes if classesToDex is null. 59f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 60f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * @throws IOException 61f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project */ 62f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public dex.structure.DexFile getFrom(Set<JavaSource> sources, 63f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project Set<String> classesToDex) throws IOException { 64f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project Set<MemoryByteCode> byteCodeInMemory = compileToByteCode(sources); 65f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 66f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project byte[] dexCode = convertToDexCode(byteCodeInMemory, classesToDex); 67f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project DexBuffer dexBuffer = new DexBuffer(dexCode); 68f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project DexFileReader reader = new DexFileReader(); 69f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return reader.read(dexBuffer); 70f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 71f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 72f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 73f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private byte[] convertToDexCode(Set<MemoryByteCode> byteCodeInMemory, Set<String> classNamesToDex) throws IOException { 74f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project CfOptions cfOptions = new CfOptions(); 75f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project DexFile dexFile = new DexFile(); 76f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (MemoryByteCode memoryByteCode : byteCodeInMemory) { 77f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if(classNamesToDex == null || classNamesToDex.contains(memoryByteCode.getName())) { 78f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project ClassDefItem classDefItem = CfTranslator.translate(memoryByteCode.getName().replace('.', '/') +".class", memoryByteCode.getBytes(), cfOptions); 79f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project dexFile.add(classDefItem); 80f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 81f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 82f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return dexFile.toDex(null, false); 83f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 84f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 85f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 86f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public Set<MemoryByteCode> compileToByteCode(Set<JavaSource> source) { 87f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); 88f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>(); 89f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, 90f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project null, null); 91f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm); 92f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 93f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays 94f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project .asList(new String[] {"-classpath", "."}), null, source); 95f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project boolean success = compile.call(); 96f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if(!success) { 97f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project StringBuilder errorMessage = new StringBuilder(); 98f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) { 99f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project errorMessage.append(dia); 100f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 101f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project throw new IllegalStateException(errorMessage.toString()); 102f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 103f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return xfm.getAllMemoryByteCodes(); 104f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 105f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project} 106f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 107f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 108f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 109f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 110f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 111f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 112