upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1,382 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import dex.reader.util.JavaSource;
import dex.structure.DexAnnotation;
import dex.structure.DexAnnotationAttribute;
import dex.structure.DexClass;
import dex.structure.DexEncodedValue;
import dex.structure.DexField;
import dex.structure.DexFile;
import dex.structure.DexMethod;
import dex.structure.DexParameter;
public class DexFileReaderTests extends DexTestsCommon {
private static final String LDALVIK_ANNOTATION_SIGNATURE = "Ldalvik/annotation/Signature;";
JavaSource A = new JavaSource("a.b.c.A",
"package a.b.c; public class A{ public void get() {}}"
);
@Test
public void testA() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(A);
assertEquals(1, dexFile.getDefinedClasses().size());
@SuppressWarnings("unused")
DexClass class1 = getClass(dexFile, "La/b/c/A;");
System.out.println(dexFile);
}
JavaSource T0 = new JavaSource("T0",
"public class T0 {" +
" public int publicIntField;" +
" protected long protectedLongField;" +
" short defaultShortField;" +
" private double privateDoubleField;" +
" " +
" public String publicStringMethodInt(int a){ return \"bla\"; }" +
" protected String protectedStringMethodInt(int a){ return \"bla\"; }" +
" String defaultStringMethodInt(int a){ return \"bla\"; }" +
" private String privateStringMethodInt(int a){ return \"bla\"; }" +
"}"
);
/**
* Tests parsing a simple class.
*/
@Test
public void testT0() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(T0);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass clazz = dexFile.getDefinedClasses().get(0);
assertEquals("LT0;", clazz.getName());
assertPublic(clazz);
//fields
assertEquals(4, clazz.getFields().size());
DexField field = getField(clazz, "publicIntField");
assertPublic(field);
field = getField(clazz, "protectedLongField");
assertProtected(field);
field = getField(clazz, "defaultShortField");
assertDefault(field);
field = getField(clazz, "privateDoubleField");
assertPrivate(field);
//methods
DexMethod method = getMethod(clazz, "publicStringMethodInt", "I");
assertPublic(method);
method = getMethod(clazz, "protectedStringMethodInt", "I");/** a.b.C */
assertProtected(method);
method = getMethod(clazz, "defaultStringMethodInt", "I");
assertDefault(method);
method = getMethod(clazz, "privateStringMethodInt", "I");
assertPrivate(method);
}
JavaSource T1 = new JavaSource( "T1","public class T1 extends T0 {}" );
private static Set<JavaSource> toSet(JavaSource...javaSources){
return new HashSet<JavaSource>(Arrays.asList(javaSources));
}
private static Set<String> toStringSet(JavaSource... javaSources) {
Set<String> names = new HashSet<String>();
for (JavaSource javaSource : javaSources) {
names.add(javaSource.getName());
}
return names;
}
private static Set<String> toStringSet(String... javaSourceName) {
return new HashSet<String>(Arrays.asList(javaSourceName));
}
/**
* Tests parsing a simple sub class.
* @throws IOException
*/
@Test
public void testT1() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(toSet(T1, T0), toStringSet(T1));
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass clazz = dexFile.getDefinedClasses().get(0);
assertEquals("LT1;", clazz.getName());
assertPublic(clazz);
assertEquals("LT0;", clazz.getSuperClass());
}
/**
* Tests parsing T0 and T1 from same dex file.
*
* @throws IOException
*/
@Test
public void testT0_T1() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(T1, T0);
assertEquals(2, dexFile.getDefinedClasses().size());
DexClass T0 = getClass(dexFile, "LT0;");
assertPublic(T0);
DexClass T1 = getClass(dexFile, "LT1;");
assertPublic(T1);
assertEquals(T1.getSuperClass(), T0.getName());
}
static final JavaSource A0 = new JavaSource("A0",
"import java.lang.annotation.*;" +
"@Retention(RetentionPolicy.RUNTIME)" +
"@Target(ElementType.TYPE)" +
"public @interface A0 {}"
);
/**
* Tests parsing Annotation Declaration.
*/
@Test
public void testA0() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(A0);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass A0 = getClass(dexFile, "LA0;");
assertPublic(A0);
assertEquals(2, A0.getAnnotations().size());
}
static final JavaSource T3 = new JavaSource("T3",
"import java.io.*;" +
"@A0 " +
"public final class T3 {}"
);
/**
* Tests parsing Annotated Class.
*/
@Test
public void testA0_T3() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(T3, A0);
assertEquals(2, dexFile.getDefinedClasses().size());
DexClass T3 = getClass(dexFile, "LT3;");
assertPublic(T3);
assertEquals(1, T3.getAnnotations().size());
DexAnnotation annotation = getAnnotation(T3, "LA0;");
DexClass A0 = getClass(dexFile, "LA0;");
assertEquals(A0.getName(), annotation.getTypeName());
}
static final JavaSource G0 = new JavaSource("G0","public class G0<T>{}");
/**
* Tests parsing Generic Type.
*/
@Test
public void testG0() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(G0);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass G0 = getClass(dexFile, "LG0;");
assertPublic(G0);
DexAnnotation sig = getAnnotation(G0, LDALVIK_ANNOTATION_SIGNATURE);
assertEquals(1, sig.getAttributes().size());
DexAnnotationAttribute dexAnnotationValue = sig.getAttributes().get(0);
assertNotNull(dexAnnotationValue.getEncodedValue());
Object value = dexAnnotationValue.getEncodedValue().getValue();
assertTrue(value instanceof List);
StringBuilder builder = new StringBuilder();
for (Object o : (List<?>)value) {
builder.append(((DexEncodedValue)o).getValue());
}
//FIXME verify
assertEquals("<T:Ljava/lang/Object;>Ljava/lang/Object;", builder.toString());
}
static final JavaSource G1 = new JavaSource("G1","public class G1<T extends G1>{}");
/**
* Tests parsing Generic Type.
*/
@Test
public void testG1() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(G1);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass G1 = getClass(dexFile, "LG1;");
assertPublic(G1);
DexAnnotation sig = getAnnotation(G1, LDALVIK_ANNOTATION_SIGNATURE);
assertEquals(1, sig.getAttributes().size());
DexAnnotationAttribute dexAnnotationValue = sig.getAttributes().get(0);
assertNotNull(dexAnnotationValue.getEncodedValue());
Object value = dexAnnotationValue.getEncodedValue().getValue();
assertTrue(value instanceof List);
StringBuilder builder = new StringBuilder();
for (Object o : (List<?>)value) {
builder.append(((DexEncodedValue)o).getValue());
}
//FIXME verify
assertEquals("<T:LG1;>Ljava/lang/Object;", builder.toString());
}
static final JavaSource I0 = new JavaSource("I0",
"import java.io.Serializable;" +
"public interface I0 extends Serializable {}"
);
/**
* Tests parsing Interface Type.
*/
@Test
public void testI0() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(I0);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass I0 = getClass(dexFile, "LI0;");
assertPublic(I0);
assertTrue(Modifier.isInterface(I0.getModifiers()));
assertEquals(1, I0.getInterfaces().size());
assertEquals("Ljava/io/Serializable;", I0.getInterfaces().get(0));
}
static final JavaSource Outer0 = new JavaSource("Outer0",
"public class Outer0 {" +
" static class StaticInner {}" +
" class Inner{}" +
"}"
);
/**
* Tests parsing Interface Type.
* @throws IOException
*/
@SuppressWarnings("unchecked")
@Test
public void testOuter0() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(toSet(Outer0), toStringSet("Outer0", "Outer0$Inner", "Outer0$StaticInner"));
assertEquals(3, dexFile.getDefinedClasses().size());
DexClass Outer0 = getClass(dexFile, "LOuter0;");
DexAnnotation sig = getAnnotation(Outer0, "Ldalvik/annotation/MemberClasses;");
assertEquals(1, sig.getAttributes().size());
DexAnnotationAttribute dexAnnotationValue = sig.getAttributes().get(0);
assertNotNull(dexAnnotationValue.getEncodedValue());
List<DexEncodedValue> values = (List<DexEncodedValue>) dexAnnotationValue.getEncodedValue().getValue();
Set<String> innerTypeNames = new HashSet<String>();
for (DexEncodedValue value : values) {
innerTypeNames.add((String) value.getValue());
}
DexClass inner = getClass(dexFile, "LOuter0$Inner;");
DexClass staticInner = getClass(dexFile, "LOuter0$StaticInner;");
assertTrue(innerTypeNames.contains(inner.getName()));
assertTrue(innerTypeNames.contains(staticInner.getName()));
}
static final JavaSource parameterAnnotation = new JavaSource("A",
"public class A {" +
" void m(@Deprecated int a) {}" +
"}");
/**
* Tests parameter annotation.
*
* @throws IOException
*/
@Test
public void testParameterAnnotation() throws IOException {
DexFile dexFile = javaToDexUtil.getFrom(parameterAnnotation);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass A = getClass(dexFile, "LA;");
DexMethod method = getMethod(A, "m", "I");
assertEquals(1, method.getParameters().size());
DexParameter dexParameter = method.getParameters().get(0);
assertEquals("I", dexParameter.getTypeName());
assertEquals(1, dexParameter.getAnnotations().size());
DexAnnotation annotation = dexParameter.getAnnotations().iterator().next();
assertEquals("Ljava/lang/Deprecated;", annotation.getTypeName());
}
@Test
public void testEnum() throws IOException {
JavaSource source = new JavaSource("E", "public enum E { A,B; public static final E C = null; }");
DexFile dexFile = javaToDexUtil.getFrom(source);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass E = getClass(dexFile, "LE;");
System.out.println(E);
System.out.println(E.getFields());
}
/**
* Tests parsing of huge dex file.
* @throws IOException
*/
@Test
public void testAllReader() throws IOException {
FileWriter w = new FileWriter("dex/classes.out.dex");
DexFileReader dexReader = new DexFileReader();
DexFile dexFile = dexReader.read(new DexBuffer("dex/classes.dex"));
TypeFormatter formatter = new TypeFormatter();
w.append(formatter.formatDexFile(dexFile));
w.flush();
w.close();
assertTrue(true);
}
/**
* Tests parsing of huge dex file.
* @throws IOException
*/
@Test
public void testAllReader0() throws IOException {
FileWriter w = new FileWriter("dex/classes0.out.dex");
DexFileReader dexReader = new DexFileReader();
DexFile dexFile = dexReader.read(new DexBuffer("dex/classes0.dex"));
TypeFormatter formatter = new TypeFormatter();
w.append(formatter.formatDexFile(dexFile));
w.flush();
w.close();
assertTrue(true);
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.After;
import org.junit.Before;
import dex.reader.util.JavaSourceToDexUtil;
import dex.structure.DexAnnotatedElement;
import dex.structure.DexAnnotation;
import dex.structure.DexClass;
import dex.structure.DexField;
import dex.structure.DexFile;
import dex.structure.DexMethod;
import dex.structure.DexParameter;
import dex.structure.WithModifiers;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class DexTestsCommon {
protected JavaSourceToDexUtil javaToDexUtil;
@Before
public void initializeJavaToDexUtil() {
javaToDexUtil = new JavaSourceToDexUtil();
}
@After
public void shutdownJavaToDexUtil() {
javaToDexUtil = null;
}
public static void assertPublic(WithModifiers withMod) {
assertTrue(Modifier.isPublic(withMod.getModifiers()));
assertFalse(Modifier.isPrivate(withMod.getModifiers())
|| Modifier.isProtected(withMod.getModifiers()));
}
public static void assertProtected(WithModifiers withMod) {
assertTrue(Modifier.isProtected(withMod.getModifiers()));
assertFalse(Modifier.isPrivate(withMod.getModifiers())
|| Modifier.isPublic(withMod.getModifiers()));
}
public static void assertPrivate(WithModifiers withMod) {
assertTrue(Modifier.isPrivate(withMod.getModifiers()));
assertFalse(Modifier.isProtected(withMod.getModifiers())
|| Modifier.isPublic(withMod.getModifiers()));
}
public static void assertDefault(WithModifiers withMod) {
assertFalse(Modifier.isPrivate(withMod.getModifiers())
|| Modifier.isProtected(withMod.getModifiers())
|| Modifier.isPublic(withMod.getModifiers()));
}
/**
* Creates and returns a dex file from the specified file.
*
* @param fileName the name of the file to read
* @return the dex file
* @throws IOException if the file is not accessible
*/
protected DexFile prepareDexFile(String fileName) throws IOException{
DexFileReader dexReader = new DexFileReader();
return dexReader.read(new DexBuffer(fileName));
}
protected DexClass getClass(DexFile file, String className) {
assertNotNull(file);
assertNotNull(className);
for (DexClass clazz : file.getDefinedClasses()) {
if(className.equals(clazz.getName())){
return clazz;
}
}
fail("Class: " + className +" not present in file: " + file.getName());
throw new IllegalArgumentException("Class: " + className +" not present in file: " + file.getName());
}
protected DexField getField(DexClass clazz, String fieldName) {
assertNotNull(clazz);
assertNotNull(fieldName);
for (DexField field : clazz.getFields()) {
if(fieldName.equals(field.getName())){
return field;
}
}
fail("Field: " + fieldName +" not present in class: " + clazz.getName());
throw new IllegalArgumentException("Field: " + fieldName +" not present in class: " + clazz.getName());
}
protected DexAnnotation getAnnotation(DexAnnotatedElement element, String annotationType) {
assertNotNull(element);
assertNotNull(annotationType);
for (DexAnnotation anno : element.getAnnotations()) {
if(annotationType.equals(anno.getTypeName())){
return anno;
}
}
fail("Annotation: " + annotationType +" not present in Element.");
throw new IllegalArgumentException("Annotation: " + annotationType +" not present in Element.");
}
protected DexMethod getMethod(DexClass clazz, String methodName, String... typeNames) {
assertNotNull(clazz);
assertNotNull(methodName);
List<String> paramTypeNames = Arrays.asList(typeNames);
for (DexMethod method : clazz.getMethods()) {
List<String> methodsParamTypeNames = getParamTypeNames(method.getParameters());
if(methodName.equals(method.getName()) && paramTypeNames.equals(methodsParamTypeNames)){
return method;
}
}
fail("Method: " + methodName +" not present in class: " + clazz.getName());
throw new IllegalArgumentException("Method: " + methodName +" not present in class: " + clazz.getName());
}
private List<String> getParamTypeNames(List<DexParameter> parameters) {
List<String> paramTypeNames = new LinkedList<String>();
for (DexParameter parameter : parameters) {
paramTypeNames.add(parameter.getTypeName());
}
return paramTypeNames;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader;
import static org.junit.Assert.assertEquals;
import dex.reader.util.JavaSource;
import dex.structure.DexClass;
import dex.structure.DexFile;
import org.junit.Test;
import java.io.IOException;
public class LargeDexTests extends DexTestsCommon{
/**
* Tests parsing a class with 10000 Fields.
*/
@Test
public void testManyFields() throws IOException{
String CLASS_NAME = "L0";
int NR_OF_FIELDS = 10000;
StringBuilder b = new StringBuilder();
b.append("public class ").append(CLASS_NAME).append("{\n");
for (int i = 0; i < NR_OF_FIELDS; i++) {
b.append("\tpublic int f").append(i).append(";\n");
}
b.append("}\n");
JavaSource source = new JavaSource(CLASS_NAME, b.toString());
DexFile dexFile = javaToDexUtil.getFrom(source);
assertEquals(1, dexFile.getDefinedClasses().size());
DexClass clazz = dexFile.getDefinedClasses().get(0);
assertEquals("LL0;", clazz.getName());
assertPublic(clazz);
assertEquals(NR_OF_FIELDS, clazz.getFields().size());
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
/**
* {@code JavaSource} represents an in-memory java source.
*/
public class JavaSource extends SimpleJavaFileObject {
private String src;
private final String sourceName;
public JavaSource(String sourceName, String sourceCode) {
super(URI.create("string:///" + sourceName.replace(".", "/") + ".java"),
Kind.SOURCE);
this.sourceName = sourceName;
this.src = sourceCode;
}
@Override
public String getName() {
return sourceName;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return src;
}
public OutputStream openOutputStream() {
throw new IllegalStateException();
}
public InputStream openInputStream() {
return new ByteArrayInputStream(src.getBytes());
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader.util;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import com.android.dx.dex.cf.CfOptions;
import com.android.dx.dex.cf.CfTranslator;
import com.android.dx.dex.file.ClassDefItem;
import com.android.dx.dex.file.DexFile;
import dex.reader.DexBuffer;
import dex.reader.DexFileReader;
public class JavaSourceToDexUtil {
public dex.structure.DexFile getFrom(JavaSource source) throws IOException{
return getAllFrom(Collections.singleton(source));
}
public dex.structure.DexFile getFrom(JavaSource... source) throws IOException{
return getAllFrom(new HashSet<JavaSource>(Arrays.asList(source)));
}
public dex.structure.DexFile getAllFrom(Set<JavaSource> sources) throws IOException{
return getFrom(sources, null);
}
/**
* Converts java source code to a {@link dex.structure.DexFile} loaded by
* {@link DexFileReader}. Converts only classes with the specified name in
* classesToDex or all classes if classesToDex is null.
*
* @throws IOException
*/
public dex.structure.DexFile getFrom(Set<JavaSource> sources,
Set<String> classesToDex) throws IOException {
Set<MemoryByteCode> byteCodeInMemory = compileToByteCode(sources);
byte[] dexCode = convertToDexCode(byteCodeInMemory, classesToDex);
DexBuffer dexBuffer = new DexBuffer(dexCode);
DexFileReader reader = new DexFileReader();
return reader.read(dexBuffer);
}
private byte[] convertToDexCode(Set<MemoryByteCode> byteCodeInMemory, Set<String> classNamesToDex) throws IOException {
CfOptions cfOptions = new CfOptions();
DexFile dexFile = new DexFile();
for (MemoryByteCode memoryByteCode : byteCodeInMemory) {
if(classNamesToDex == null || classNamesToDex.contains(memoryByteCode.getName())) {
ClassDefItem classDefItem = CfTranslator.translate(memoryByteCode.getName().replace('.', '/') +".class", memoryByteCode.getBytes(), cfOptions);
dexFile.add(classDefItem);
}
}
return dexFile.toDex(null, false);
}
public Set<MemoryByteCode> compileToByteCode(Set<JavaSource> source) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol,
null, null);
SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm);
CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays
.asList(new String[] {"-classpath", "."}), null, source);
boolean success = compile.call();
if(!success) {
StringBuilder errorMessage = new StringBuilder();
for (Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
errorMessage.append(dia);
}
throw new IllegalStateException(errorMessage.toString());
}
return xfm.getAllMemoryByteCodes();
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader.util;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
/**
* {@code MemoryByteCode} represents an in-memory java byte code.
*/
/* package */ class MemoryByteCode extends SimpleJavaFileObject {
private ByteArrayOutputStream baos;
private final String name;
public MemoryByteCode(String name) {
super(URI.create("byte:///" + name.replace(".", "/") + ".class"),
Kind.CLASS);
this.name = name;
}
@Override
public String getName() {
return name;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
throw new IllegalStateException();
}
public OutputStream openOutputStream() {
baos = new ByteArrayOutputStream();
return baos;
}
public InputStream openInputStream() {
throw new IllegalStateException();
}
public byte[] getBytes() {
return baos.toByteArray();
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dex.reader.util;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
/**
* {@code SpecialJavaFileManager} is a file manager which returns
* {@link MemoryByteCode} objects for its output and keeps track of them.
*/
/* package */ class SpecialJavaFileManager extends
ForwardingJavaFileManager<StandardJavaFileManager> {
private Map<String, MemoryByteCode> store;
public SpecialJavaFileManager(StandardJavaFileManager sjfm) {
super(sjfm);
store = new HashMap<String, MemoryByteCode>();
}
public JavaFileObject getJavaFileForOutput(Location location, String name,
JavaFileObject.Kind kind, FileObject sibling) {
MemoryByteCode mbc = new MemoryByteCode(name);
store.put(name, mbc);
return mbc;
}
public Set<MemoryByteCode> getAllMemoryByteCodes() {
return new HashSet<MemoryByteCode>(store.values());
}
public MemoryByteCode getMemoryByteCode(String className) {
return store.get(className);
}
}