diff options
author | Paul Duffin <paulduffin@google.com> | 2017-06-20 16:18:07 +0100 |
---|---|---|
committer | Paul Duffin <paulduffin@google.com> | 2017-06-26 17:00:21 +0100 |
commit | aaaba76810c0b5b61c609a929536b64ac7e368fc (patch) | |
tree | 9dabcf4edf22526ff3a057fcd5a0bb2d0be0ae53 /test-runner/src/android | |
parent | 3c5ab7d3243e646137d9e60c2a54ffc907a85a27 (diff) |
Clean up ClassPathPackageInfoSource
Part of the work of removing JUnit and dependent android.test classes
from the Android API involves providing a static library that developers
can include in their test applications to ease migration. That library
will be built directly from the source (as opposed to android.jar which
is built from stubs) and so developers will be able to see classes and
methods that are not present in the stubs. This change is one of a
number of similar changes that cleanup the existing non-API code in
order to minimize the additional methods and classes exposed externally.
The basic approach is to remove unused classes and methods, use least
visible access modifier possible and generally minimize the amount of
publicly visible code.
PackageInfoSources only provided a static field and accessor method so
they were moved into ClassPathPackageInfoSource and PackageInfoSources
was removed.
ClassPathPackageInfo was only used in ClassPathPackageInfoSource and in
TestGrouping. In the latter it was simply used as an intermediate value
between ClassPathPackageInfoSource.getPackage(String packageName) and
ClassPathPackageInfo.getTopLevelClassesRecursive(String packageName).
Moving that method into ClassPathPackageInfoSource allowed the
ClassPathPackageInfo to become an inner class of
ClassPathPackageInfoSource. As it is an inner class it no longer needed
an explicit reference to the containing ClassPathPackageInfoSource.
Bug: 30188076
Test: make checkbuild and ran FrameworkTestRunnerTests
Change-Id: Idb0b6a585030805b9cff8562abb93b7e5920c53a
Diffstat (limited to 'test-runner/src/android')
4 files changed, 73 insertions, 244 deletions
diff --git a/test-runner/src/android/test/ClassPathPackageInfo.java b/test-runner/src/android/test/ClassPathPackageInfo.java deleted file mode 100644 index 2cf76afa1d94..000000000000 --- a/test-runner/src/android/test/ClassPathPackageInfo.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2008 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 android.test; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * The Package object doesn't allow you to iterate over the contained - * classes and subpackages of that package. This is a version that does. - * - * {@hide} Not needed for 1.0 SDK. - */ -@Deprecated -public class ClassPathPackageInfo { - - private final ClassPathPackageInfoSource source; - private final String packageName; - private final Set<String> subpackageNames; - private final Set<Class<?>> topLevelClasses; - - ClassPathPackageInfo(ClassPathPackageInfoSource source, String packageName, - Set<String> subpackageNames, Set<Class<?>> topLevelClasses) { - this.source = source; - this.packageName = packageName; - this.subpackageNames = Collections.unmodifiableSet(subpackageNames); - this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses); - } - - public Set<ClassPathPackageInfo> getSubpackages() { - Set<ClassPathPackageInfo> info = new HashSet<>(); - for (String name : subpackageNames) { - info.add(source.getPackageInfo(name)); - } - return info; - } - - public Set<Class<?>> getTopLevelClassesRecursive() { - Set<Class<?>> set = new HashSet<>(); - addTopLevelClassesTo(set); - return set; - } - - private void addTopLevelClassesTo(Set<Class<?>> set) { - set.addAll(topLevelClasses); - for (ClassPathPackageInfo info : getSubpackages()) { - info.addTopLevelClassesTo(set); - } - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ClassPathPackageInfo) { - ClassPathPackageInfo that = (ClassPathPackageInfo) obj; - return (this.packageName).equals(that.packageName); - } - return false; - } - - @Override - public int hashCode() { - return packageName.hashCode(); - } -} diff --git a/test-runner/src/android/test/ClassPathPackageInfoSource.java b/test-runner/src/android/test/ClassPathPackageInfoSource.java index 9bcc25adf8d3..755b540cbbb8 100644 --- a/test-runner/src/android/test/ClassPathPackageInfoSource.java +++ b/test-runner/src/android/test/ClassPathPackageInfoSource.java @@ -21,15 +21,12 @@ import dalvik.system.DexFile; import java.io.File; import java.io.IOException; +import java.util.Collections; import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; /** * Generate {@link ClassPathPackageInfo}s by scanning apk paths. @@ -39,11 +36,13 @@ import java.util.zip.ZipFile; @Deprecated public class ClassPathPackageInfoSource { - private static final String CLASS_EXTENSION = ".class"; - private static final ClassLoader CLASS_LOADER = ClassPathPackageInfoSource.class.getClassLoader(); + private static String[] apkPaths; + + private static ClassPathPackageInfoSource classPathSource; + private final SimpleCache<String, ClassPathPackageInfo> cache = new SimpleCache<String, ClassPathPackageInfo>() { @Override @@ -54,23 +53,28 @@ public class ClassPathPackageInfoSource { // The class path of the running application private final String[] classPath; - private static String[] apkPaths; - // A cache of jar file contents - private final Map<File, Set<String>> jarFiles = new HashMap<>(); - private ClassLoader classLoader; + private final ClassLoader classLoader; - ClassPathPackageInfoSource() { + private ClassPathPackageInfoSource(ClassLoader classLoader) { + this.classLoader = classLoader; classPath = getClassPath(); } - - public static void setApkPaths(String[] apkPaths) { + static void setApkPaths(String[] apkPaths) { ClassPathPackageInfoSource.apkPaths = apkPaths; } - public ClassPathPackageInfo getPackageInfo(String pkgName) { - return cache.get(pkgName); + public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) { + if (classPathSource == null) { + classPathSource = new ClassPathPackageInfoSource(classLoader); + } + return classPathSource; + } + + public Set<Class<?>> getTopLevelClassesRecursive(String packageName) { + ClassPathPackageInfo packageInfo = cache.get(packageName); + return packageInfo.getTopLevelClassesRecursive(); } private ClassPathPackageInfo createPackageInfo(String packageName) { @@ -96,7 +100,7 @@ public class ClassPathPackageInfoSource { + "'. Message: " + e.getMessage(), e); } } - return new ClassPathPackageInfo(this, packageName, subpackageNames, + return new ClassPathPackageInfo(packageName, subpackageNames, topLevelClasses); } @@ -107,9 +111,6 @@ public class ClassPathPackageInfoSource { */ private void findClasses(String packageName, Set<String> classNames, Set<String> subpackageNames) { - String packagePrefix = packageName + '.'; - String pathPrefix = packagePrefix.replace('.', '/'); - for (String entryName : classPath) { File classPathEntry = new File(entryName); @@ -150,58 +151,6 @@ public class ClassPathPackageInfoSource { /** * Finds all classes and sub packages that are below the packageName and - * add them to the respective sets. Searches the package in a class directory. - */ - private void findClassesInDirectory(File classDir, - String packagePrefix, String pathPrefix, Set<String> classNames, - Set<String> subpackageNames) - throws IOException { - File directory = new File(classDir, pathPrefix); - - if (directory.exists()) { - for (File f : directory.listFiles()) { - String name = f.getName(); - if (name.endsWith(CLASS_EXTENSION) && isToplevelClass(name)) { - classNames.add(packagePrefix + getClassName(name)); - } else if (f.isDirectory()) { - subpackageNames.add(packagePrefix + name); - } - } - } - } - - /** - * Finds all classes and sub packages that are below the packageName and - * add them to the respective sets. Searches the package in a single jar file. - */ - private void findClassesInJar(File jarFile, String pathPrefix, - Set<String> classNames, Set<String> subpackageNames) - throws IOException { - Set<String> entryNames = getJarEntries(jarFile); - // check if the Jar contains the package. - if (!entryNames.contains(pathPrefix)) { - return; - } - int prefixLength = pathPrefix.length(); - for (String entryName : entryNames) { - if (entryName.startsWith(pathPrefix)) { - if (entryName.endsWith(CLASS_EXTENSION)) { - // check if the class is in the package itself or in one of its - // subpackages. - int index = entryName.indexOf('/', prefixLength); - if (index >= 0) { - String p = entryName.substring(0, index).replace('/', '.'); - subpackageNames.add(p); - } else if (isToplevelClass(entryName)) { - classNames.add(getClassName(entryName).replace('/', '.')); - } - } - } - } - } - - /** - * Finds all classes and sub packages that are below the packageName and * add them to the respective sets. Searches the package in a single apk file. */ private void findClassesInApk(String apkPath, String packageName, @@ -242,47 +191,6 @@ public class ClassPathPackageInfoSource { } /** - * Gets the class and package entries from a Jar. - */ - private Set<String> getJarEntries(File jarFile) - throws IOException { - Set<String> entryNames = jarFiles.get(jarFile); - if (entryNames == null) { - entryNames = new HashSet<>(); - ZipFile zipFile = new ZipFile(jarFile); - Enumeration<? extends ZipEntry> entries = zipFile.entries(); - while (entries.hasMoreElements()) { - String entryName = entries.nextElement().getName(); - if (entryName.endsWith(CLASS_EXTENSION)) { - // add the entry name of the class - entryNames.add(entryName); - - // add the entry name of the classes package, i.e. the entry name of - // the directory that the class is in. Used to quickly skip jar files - // if they do not contain a certain package. - // - // Also add parent packages so that a JAR that contains - // pkg1/pkg2/Foo.class will be marked as containing pkg1/ in addition - // to pkg1/pkg2/ and pkg1/pkg2/Foo.class. We're still interested in - // JAR files that contains subpackages of a given package, even if - // an intermediate package contains no direct classes. - // - // Classes in the default package will cause a single package named - // "" to be added instead. - int lastIndex = entryName.lastIndexOf('/'); - do { - String packageName = entryName.substring(0, lastIndex + 1); - entryNames.add(packageName); - lastIndex = entryName.lastIndexOf('/', lastIndex - 1); - } while (lastIndex > 0); - } - } - jarFiles.put(jarFile, entryNames); - } - return entryNames; - } - - /** * Checks if a given file name represents a toplevel class. */ private static boolean isToplevelClass(String fileName) { @@ -290,14 +198,6 @@ public class ClassPathPackageInfoSource { } /** - * Given the absolute path of a class file, return the class name. - */ - private static String getClassName(String className) { - int classNameEnd = className.length() - CLASS_EXTENSION.length(); - return className.substring(0, classNameEnd); - } - - /** * Gets the class path from the System Property "java.class.path" and splits * it up into the individual elements. */ @@ -307,7 +207,56 @@ public class ClassPathPackageInfoSource { return classPath.split(Pattern.quote(separator)); } - public void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; + /** + * The Package object doesn't allow you to iterate over the contained + * classes and subpackages of that package. This is a version that does. + */ + private class ClassPathPackageInfo { + + private final String packageName; + private final Set<String> subpackageNames; + private final Set<Class<?>> topLevelClasses; + + private ClassPathPackageInfo(String packageName, + Set<String> subpackageNames, Set<Class<?>> topLevelClasses) { + this.packageName = packageName; + this.subpackageNames = Collections.unmodifiableSet(subpackageNames); + this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses); + } + + private Set<ClassPathPackageInfo> getSubpackages() { + Set<ClassPathPackageInfo> info = new HashSet<>(); + for (String name : subpackageNames) { + info.add(cache.get(name)); + } + return info; + } + + private Set<Class<?>> getTopLevelClassesRecursive() { + Set<Class<?>> set = new HashSet<>(); + addTopLevelClassesTo(set); + return set; + } + + private void addTopLevelClassesTo(Set<Class<?>> set) { + set.addAll(topLevelClasses); + for (ClassPathPackageInfo info : getSubpackages()) { + info.addTopLevelClassesTo(set); + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ClassPathPackageInfo) { + ClassPathPackageInfo that = (ClassPathPackageInfo) obj; + return (this.packageName).equals(that.packageName); + } + return false; + } + + @Override + public int hashCode() { + return packageName.hashCode(); + } } } diff --git a/test-runner/src/android/test/PackageInfoSources.java b/test-runner/src/android/test/PackageInfoSources.java deleted file mode 100644 index 205f86b04d5f..000000000000 --- a/test-runner/src/android/test/PackageInfoSources.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2008 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 android.test; - -/** - * {@hide} Not needed for SDK. - */ -@Deprecated -public class PackageInfoSources { - - private static ClassPathPackageInfoSource classPathSource; - - private PackageInfoSources() { - } - - public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) { - if (classPathSource == null) { - classPathSource = new ClassPathPackageInfoSource(); - classPathSource.setClassLoader(classLoader); - } - return classPathSource; - } - -} diff --git a/test-runner/src/android/test/suitebuilder/TestGrouping.java b/test-runner/src/android/test/suitebuilder/TestGrouping.java index 307afb55e47a..030bc426ac19 100644 --- a/test-runner/src/android/test/suitebuilder/TestGrouping.java +++ b/test-runner/src/android/test/suitebuilder/TestGrouping.java @@ -16,9 +16,7 @@ package android.test.suitebuilder; -import android.test.ClassPathPackageInfo; import android.test.ClassPathPackageInfoSource; -import android.test.PackageInfoSources; import android.util.Log; import com.android.internal.util.Predicate; import junit.framework.TestCase; @@ -131,10 +129,9 @@ class TestGrouping { } private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) { - ClassPathPackageInfoSource source = PackageInfoSources.forClassPath(classLoader); - ClassPathPackageInfo packageInfo = source.getPackageInfo(packageName); + ClassPathPackageInfoSource source = ClassPathPackageInfoSource.forClassPath(classLoader); - return selectTestClasses(packageInfo.getTopLevelClassesRecursive()); + return selectTestClasses(source.getTopLevelClassesRecursive(packageName)); } @SuppressWarnings("unchecked") |