aboutsummaryrefslogtreecommitdiffstats
path: root/apigenerator/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'apigenerator/src/com/android')
-rw-r--r--apigenerator/src/com/android/apigenerator/AndroidJarReader.java253
-rw-r--r--apigenerator/src/com/android/apigenerator/ApiClass.java205
-rw-r--r--apigenerator/src/com/android/apigenerator/Main.java79
3 files changed, 0 insertions, 537 deletions
diff --git a/apigenerator/src/com/android/apigenerator/AndroidJarReader.java b/apigenerator/src/com/android/apigenerator/AndroidJarReader.java
deleted file mode 100644
index 07a3ce6..0000000
--- a/apigenerator/src/com/android/apigenerator/AndroidJarReader.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.apigenerator;
-
-import com.android.utils.Pair;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * Reads all the android.jar files found in an SDK and generate a map of {@link ApiClass}.
- *
- */
-public class AndroidJarReader {
-
- private static final byte[] BUFFER = new byte[65535];
-
- private final String mSdkFolder;
-
- public AndroidJarReader(String sdkFolder) {
- mSdkFolder = sdkFolder;
- }
-
- public Map<String, ApiClass> getClasses() {
- HashMap<String, ApiClass> map = new HashMap<String, ApiClass>();
-
- // Get all the android.jar. They are in platforms-#
- int apiLevel = 0;
- while (true) {
- apiLevel++;
- try {
- File jar = new File(mSdkFolder, "platforms/android-" + apiLevel + "/android.jar");
- if (jar.exists() == false) {
- System.out.println("Last API level found: " + (apiLevel-1));
- break;
- }
-
- FileInputStream fis = new FileInputStream(jar);
- ZipInputStream zis = new ZipInputStream(fis);
- ZipEntry entry = zis.getNextEntry();
- while (entry != null) {
- String name = entry.getName();
-
- if (name.endsWith(".class")) {
-
- int index = 0;
- do {
- int size = zis.read(BUFFER, index, BUFFER.length - index);
- if (size >= 0) {
- index += size;
- } else {
- break;
- }
- } while (true);
-
- byte[] b = new byte[index];
- System.arraycopy(BUFFER, 0, b, 0, index);
-
- ClassReader reader = new ClassReader(b);
- ClassNode classNode = new ClassNode();
- reader.accept(classNode, 0 /*flags*/);
-
- if (classNode != null) {
- ApiClass theClass = addClass(map, classNode.name, apiLevel);
-
- // super class
- if (classNode.superName != null) {
- theClass.addSuperClass(classNode.superName, apiLevel);
- }
-
- // interfaces
- for (Object interfaceName : classNode.interfaces) {
- theClass.addInterface((String) interfaceName, apiLevel);
- }
-
- // fields
- for (Object field : classNode.fields) {
- FieldNode fieldNode = (FieldNode) field;
- if ((fieldNode.access & Opcodes.ACC_PRIVATE) != 0) {
- continue;
- }
- if (fieldNode.name.startsWith("this$") == false &&
- fieldNode.name.equals("$VALUES") == false) {
- theClass.addField(fieldNode.name, apiLevel);
- }
- }
-
- // methods
- for (Object method : classNode.methods) {
- MethodNode methodNode = (MethodNode) method;
- if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0) {
- continue;
- }
- if (methodNode.name.equals("<clinit>") == false) {
- theClass.addMethod(methodNode.name + methodNode.desc, apiLevel);
- }
- }
- }
- }
- entry = zis.getNextEntry();
- }
-
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
-
- }
- }
-
- postProcessClasses(map);
-
- return map;
- }
-
- private void postProcessClasses(Map<String, ApiClass> classes) {
- for (ApiClass theClass : classes.values()) {
- Map<String, Integer> methods = theClass.getMethods();
- Map<String, Integer> fixedMethods = new HashMap<String, Integer>();
-
- List<Pair<String, Integer>> superClasses = theClass.getSuperClasses();
- List<Pair<String, Integer>> interfaces = theClass.getInterfaces();
-
- methodLoop: for (Entry<String, Integer> method : methods.entrySet()) {
- String methodName = method.getKey();
- int apiLevel = method.getValue();
-
- if (methodName.startsWith("<init>(") == false) {
-
- for (Pair<String, Integer> parent : superClasses) {
- // only check the parent if it was a parent class at the introduction
- // of the method.
- if (parent.getSecond() <= apiLevel) {
- ApiClass parentClass = classes.get(parent.getFirst());
- assert parentClass != null;
- if (parentClass != null &&
- checkClassContains(theClass.getName(),
- methodName, apiLevel,
- classes, parentClass)) {
- continue methodLoop;
- }
- }
- }
-
- for (Pair<String, Integer> parent : interfaces) {
- // only check the parent if it was a parent class at the introduction
- // of the method.
- if (parent.getSecond() <= apiLevel) {
- ApiClass parentClass = classes.get(parent.getFirst());
- assert parentClass != null;
- if (parentClass != null &&
- checkClassContains(theClass.getName(),
- methodName, apiLevel,
- classes, parentClass)) {
- continue methodLoop;
- }
- }
- }
- }
-
- // if we reach here. the method isn't an override
- fixedMethods.put(methodName, method.getValue());
- }
-
- theClass.replaceMethods(fixedMethods);
- }
- }
-
- private boolean checkClassContains(String className, String methodName, int apiLevel,
- Map<String, ApiClass> classMap, ApiClass parentClass) {
-
- Integer parentMethodApiLevel = parentClass.getMethods().get(methodName);
- if (parentMethodApiLevel != null && parentMethodApiLevel <= apiLevel) {
- // the parent class has the method and it was introduced in the parent at the
- // same api level as the method, or before.
- return true;
- }
-
- // check on this class parents.
- List<Pair<String, Integer>> superClasses = parentClass.getSuperClasses();
- List<Pair<String, Integer>> interfaces = parentClass.getInterfaces();
-
- for (Pair<String, Integer> parent : superClasses) {
- // only check the parent if it was a parent class at the introduction
- // of the method.
- if (parent.getSecond() <= apiLevel) {
- ApiClass superParentClass = classMap.get(parent.getFirst());
- assert superParentClass != null;
- if (superParentClass != null && checkClassContains(className, methodName, apiLevel,
- classMap, superParentClass)) {
- return true;
- }
- }
- }
-
- for (Pair<String, Integer> parent : interfaces) {
- // only check the parent if it was a parent class at the introduction
- // of the method.
- if (parent.getSecond() <= apiLevel) {
- ApiClass superParentClass = classMap.get(parent.getFirst());
- assert superParentClass != null;
- if (superParentClass != null && checkClassContains(className, methodName, apiLevel,
- classMap, superParentClass)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- private ApiClass addClass(HashMap<String, ApiClass> classes, String name, int apiLevel) {
- ApiClass theClass = classes.get(name);
- if (theClass == null) {
- theClass = new ApiClass(name, apiLevel);
- classes.put(name, theClass);
- }
-
- return theClass;
- }
-}
diff --git a/apigenerator/src/com/android/apigenerator/ApiClass.java b/apigenerator/src/com/android/apigenerator/ApiClass.java
deleted file mode 100644
index 50ee8c8..0000000
--- a/apigenerator/src/com/android/apigenerator/ApiClass.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.apigenerator;
-
-import com.android.utils.Pair;
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-/**
- * Represents a class and its methods/fields.
- * This is used to write the simplified XML file containing all the public API.
- *
- */
-public class ApiClass {
-
- private final String mName;
- private final int mSince;
-
- private final List<Pair<String, Integer>> mSuperClasses =
- new ArrayList<Pair<String, Integer>>();
-
- private final List<Pair<String, Integer>> mInterfaces = new ArrayList<Pair<String, Integer>>();
-
- private final Map<String, Integer> mFields = new HashMap<String, Integer>();
- private final Map<String, Integer> mMethods = new HashMap<String, Integer>();
-
- public ApiClass(String name, int since) {
- mName = name;
- mSince = since;
- }
-
- public String getName() {
- return mName;
- }
-
- int getSince() {
- return mSince;
- }
-
- public void addField(String name, int since) {
- Integer i = mFields.get(name);
- if (i == null || i.intValue() > since) {
- mFields.put(name, Integer.valueOf(since));
- }
- }
-
- public void addMethod(String name, int since) {
- Integer i = mMethods.get(name);
- if (i == null || i.intValue() > since) {
- mMethods.put(name, Integer.valueOf(since));
- }
- }
-
- public Map<String, Integer> getMethods() {
- return mMethods;
- }
-
- public void replaceMethods(Map<String, Integer> fixedMethods) {
- mMethods.clear();
- mMethods.putAll(fixedMethods);
- }
-
- public void addSuperClass(String superClass, int since) {
- addToArray(mSuperClasses, superClass, since);
- }
-
- public List<Pair<String, Integer>> getSuperClasses() {
- return mSuperClasses;
- }
-
- public void addInterface(String interfaceClass, int since) {
- addToArray(mInterfaces, interfaceClass, since);
- }
-
- public List<Pair<String, Integer>> getInterfaces() {
- return mInterfaces;
- }
-
- void addToArray(List<Pair<String, Integer>> list, String name, int value) {
- // check if we already have that name (at a lower level)
- for (Pair<String, Integer> pair : list) {
- if (name.equals(pair.getFirst()) && pair.getSecond() < value) {
- return;
- }
- }
-
- list.add(Pair.of(name, Integer.valueOf(value)));
- }
-
- public void print(PrintStream stream) {
- stream.print("\t<class name=\"");
- stream.print(mName);
- stream.print("\" since=\"");
- stream.print(mSince);
- stream.println("\">");
-
- print(mSuperClasses, "extends", stream);
- print(mInterfaces, "implements", stream);
- print(mMethods, "method", stream);
- print(mFields, "field", stream);
-
- stream.println("\t</class>");
- }
-
- private void print(List<Pair<String, Integer> > list, String name, PrintStream stream) {
- Collections.sort(list, new Comparator<Pair<String, Integer> >() {
-
- @Override
- public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
- return o1.getFirst().compareTo(o2.getFirst());
- }
- });
-
- for (Pair<String, Integer> pair : list) {
- if (mSince == pair.getSecond()) {
- stream.print("\t\t<");
- stream.print(name);
- stream.print(" name=\"");
- stream.print(encodeAttribute(pair.getFirst()));
- stream.println("\" />");
- } else {
- stream.print("\t\t<");
- stream.print(name);
- stream.print(" name=\"");
- stream.print(encodeAttribute(pair.getFirst()));
- stream.print("\" since=\"");
- stream.print(pair.getSecond());
- stream.println("\" />");
- }
- }
- }
-
- private void print(Map<String, Integer> map, String name, PrintStream stream) {
- TreeMap<String, Integer> map2 = new TreeMap<String, Integer>(map);
-
- for (Entry<String, Integer> entry : map2.entrySet()) {
- if (mSince == entry.getValue()) {
- stream.print("\t\t<");
- stream.print(name);
- stream.print(" name=\"");
- stream.print(encodeAttribute(entry.getKey()));
- stream.println("\" />");
- } else {
- stream.print("\t\t<");
- stream.print(name);
- stream.print(" name=\"");
- stream.print(encodeAttribute(entry.getKey()));
- stream.print("\" since=\"");
- stream.print(entry.getValue());
- stream.println("\" />");
- }
- }
- }
-
- private String encodeAttribute(String attribute) {
- StringBuilder sb = new StringBuilder();
- int n = attribute.length();
- // &, ", ' and < are illegal in attributes; see http://www.w3.org/TR/REC-xml/#NT-AttValue
- // (' legal in a " string and " is legal in a ' string but here we'll stay on the safe
- // side)
- for (int i = 0; i < n; i++) {
- char c = attribute.charAt(i);
- if (c == '"') {
- sb.append("&quot;"); //$NON-NLS-1$
- } else if (c == '<') {
- sb.append("&lt;"); //$NON-NLS-1$
- } else if (c == '\'') {
- sb.append("&apos;"); //$NON-NLS-1$
- } else if (c == '&') {
- sb.append("&amp;"); //$NON-NLS-1$
- } else {
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- @Override
- public String toString() {
- return mName;
- }
-}
diff --git a/apigenerator/src/com/android/apigenerator/Main.java b/apigenerator/src/com/android/apigenerator/Main.java
deleted file mode 100644
index 4ce7ac9..0000000
--- a/apigenerator/src/com/android/apigenerator/Main.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.apigenerator;
-
-
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintStream;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Main class for command line command to convert the existing API XML/TXT files into diff-based
- * simple text files.
- *
- */
-public class Main {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- if (args.length != 2) {
- printUsage();
- }
-
- AndroidJarReader reader = new AndroidJarReader(args[0]);
- Map<String, ApiClass> classes = reader.getClasses();
- createApiFile(new File(args[1]), classes);
- }
-
- private static void printUsage() {
- System.err.println("Generates a single API file from the content of an SDK.\n");
- System.err.println("Usage\n");
- System.err.println("\tApiCheck SDKFOLDER OUTFILE\n");
- System.exit(1);
- }
-
- /**
- * Creates the simplified diff-based API level.
- * @param outFolder the out folder.
- * @param classes
- */
- private static void createApiFile(File outFile, Map<String, ApiClass> classes) {
-
- PrintStream ps = null;
- try {
- ps = new PrintStream(outFile);
- ps.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- ps.println("<api version=\"1\">");
- TreeMap<String, ApiClass> map = new TreeMap<String, ApiClass>(classes);
- for (ApiClass theClass : map.values()) {
- (theClass).print(ps);
- }
- ps.println("</api>");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } finally {
- if (ps != null) {
- ps.close();
- }
- }
- }
-}