Package com.google.common.reflect

Source Code of com.google.common.reflect.ClassPathTest$Nested

/*
* Copyright (C) 2012 The Guava Authors
*
* 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.google.common.reflect;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Closer;
import com.google.common.io.Resources;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.common.reflect.ClassPath.ResourceInfo;
import com.google.common.reflect.subpackage.ClassInSubPackage;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;

import junit.framework.TestCase;

import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

/**
* Functional tests of {@link ClassPath}.
*/
public class ClassPathTest extends TestCase {

  public void testGetResources() throws Exception {
    Map<String, ResourceInfo> byName = Maps.newHashMap();
    Map<String, ResourceInfo> byToString = Maps.newHashMap();
    ClassPath classpath = ClassPath.from(getClass().getClassLoader());
    for (ResourceInfo resource : classpath.getResources()) {
      assertThat(resource.getResourceName()).isNotEqualTo(JarFile.MANIFEST_NAME);
      assertThat(resource.toString()).isNotEqualTo(JarFile.MANIFEST_NAME);
      byName.put(resource.getResourceName(), resource);
      byToString.put(resource.toString(), resource);
      assertNotNull(resource.url());
    }
    String testResourceName = "com/google/common/reflect/test.txt";
    assertThat(byName.keySet()).containsAllOf(
        "com/google/common/reflect/ClassPath.class",
        "com/google/common/reflect/ClassPathTest.class",
        "com/google/common/reflect/ClassPathTest$Nested.class",
        testResourceName);
    assertThat(byToString.keySet()).containsAllOf(
        "com.google.common.reflect.ClassPath",
        "com.google.common.reflect.ClassPathTest",
        "com.google.common.reflect.ClassPathTest$Nested",
        testResourceName);
    assertEquals(getClass().getClassLoader().getResource(testResourceName),
        byName.get("com/google/common/reflect/test.txt").url());
  }

  public void testGetAllClasses() throws Exception {
    Set<String> names = Sets.newHashSet();
    Set<String> strings = Sets.newHashSet();
    Set<Class<?>> classes = Sets.newHashSet();
    Set<String> packageNames = Sets.newHashSet();
    Set<String> simpleNames = Sets.newHashSet();
    ClassPath classpath = ClassPath.from(getClass().getClassLoader());
    for (ClassInfo classInfo : classpath.getAllClasses()) {
      if (!classInfo.getPackageName().equals(ClassPathTest.class.getPackage().getName())) {
        continue;
      }
      names.add(classInfo.getName());
      strings.add(classInfo.toString());
      classes.add(classInfo.load());
      packageNames.add(classInfo.getPackageName());
      simpleNames.add(classInfo.getSimpleName());
    }
    class LocalClass {}
    Class<?> anonymousClass = new Object() {}.getClass();
    assertThat(names).containsAllOf(anonymousClass.getName(), LocalClass.class.getName(),
        ClassPath.class.getName(), ClassPathTest.class.getName());
    assertThat(strings).containsAllOf(anonymousClass.getName(), LocalClass.class.getName(),
        ClassPath.class.getName(), ClassPathTest.class.getName());
    assertThat(classes).containsAllOf(anonymousClass, LocalClass.class, ClassPath.class,
        ClassPathTest.class);
    assertThat(packageNames).containsExactly(ClassPath.class.getPackage().getName());
    assertThat(simpleNames).containsAllOf("", "Local", "ClassPath", "ClassPathTest");
  }

  public void testGetTopLevelClasses() throws Exception {
    Set<String> names = Sets.newHashSet();
    Set<String> strings = Sets.newHashSet();
    Set<Class<?>> classes = Sets.newHashSet();
    Set<String> packageNames = Sets.newHashSet();
    Set<String> simpleNames = Sets.newHashSet();
    ClassPath classpath = ClassPath.from(getClass().getClassLoader());
    for (ClassInfo classInfo
        : classpath.getTopLevelClasses(ClassPathTest.class.getPackage().getName())) {
      names.add(classInfo.getName());
      strings.add(classInfo.toString());
      classes.add(classInfo.load());
      packageNames.add(classInfo.getPackageName());
      simpleNames.add(classInfo.getSimpleName());
    }
    assertThat(names).containsAllOf(ClassPath.class.getName(), ClassPathTest.class.getName());
    assertThat(strings).containsAllOf(ClassPath.class.getName(), ClassPathTest.class.getName());
    assertThat(classes).containsAllOf(ClassPath.class, ClassPathTest.class);
    assertThat(packageNames).contains(ClassPath.class.getPackage().getName());
    assertThat(simpleNames).containsAllOf("ClassPath", "ClassPathTest");
    assertFalse(classes.contains(ClassInSubPackage.class));
  }

  public void testGetTopLevelClassesRecursive() throws Exception {
    Set<Class<?>> classes = Sets.newHashSet();
    ClassPath classpath = ClassPath.from(ClassPathTest.class.getClassLoader());
    for (ClassInfo classInfo
        : classpath.getTopLevelClassesRecursive(ClassPathTest.class.getPackage().getName())) {
      if (classInfo.getName().contains("ClassPathTest")) {
        System.err.println("");
      }
      classes.add(classInfo.load());
    }
    assertThat(classes).containsAllOf(ClassPathTest.class, ClassInSubPackage.class);
  }

  public void testGetTopLevelClasses_diamond() throws Exception {
    ClassLoader parent = ClassPathTest.class.getClassLoader();
    ClassLoader sub1 = new ClassLoader(parent) {};
    ClassLoader sub2 = new ClassLoader(parent) {};
    assertEquals(findClass(ClassPath.from(sub1).getTopLevelClasses(), ClassPathTest.class),
        findClass(ClassPath.from(sub2).getTopLevelClasses(), ClassPathTest.class));
  }

  public void testEquals() {
    new EqualsTester()
        .addEqualityGroup(classInfo(ClassPathTest.class), classInfo(ClassPathTest.class))
        .addEqualityGroup(classInfo(Test.class), classInfo(Test.class, getClass().getClassLoader()))
        .addEqualityGroup(
            new ResourceInfo("a/b/c.txt", getClass().getClassLoader()),
            new ResourceInfo("a/b/c.txt", getClass().getClassLoader()))
        .addEqualityGroup(
            new ResourceInfo("x.txt", getClass().getClassLoader()))
        .testEquals();
  }

  public void testClassPathEntries_emptyURLClassLoader_noParent() {
    assertThat(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet())
        .isEmpty();
  }

  public void testClassPathEntries_URLClassLoader_noParent() throws Exception {
    URL url1 = new URL("file:/a");
    URL url2 = new URL("file:/b");
    URLClassLoader classloader = new URLClassLoader(new URL[] {url1, url2}, null);
    assertEquals(
        ImmutableMap.of(url1.toURI(), classloader, url2.toURI(), classloader),
        ClassPath.getClassPathEntries(classloader));
  }

  public void testClassPathEntries_URLClassLoader_withParent() throws Exception {
    URL url1 = new URL("file:/a");
    URL url2 = new URL("file:/b");
    URLClassLoader parent = new URLClassLoader(new URL[] {url1}, null);
    URLClassLoader child = new URLClassLoader(new URL[] {url2}, parent) {};
    ImmutableMap<URI, ClassLoader> classPathEntries = ClassPath.getClassPathEntries(child);
    assertEquals(ImmutableMap.of(url1.toURI(), parent, url2.toURI(), child),  classPathEntries);
    assertThat(classPathEntries.keySet()).containsExactly(url1.toURI(), url2.toURI()).inOrder();
  }

  public void testClassPathEntries_duplicateUri_parentWins() throws Exception {
    URL url = new URL("file:/a");
    URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
    URLClassLoader child = new URLClassLoader(new URL[] {url}, parent) {};
    assertEquals(ImmutableMap.of(url.toURI(), parent), ClassPath.getClassPathEntries(child));
  }

  public void testClassPathEntries_notURLClassLoader_noParent() {
    assertThat(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty();
  }

  public void testClassPathEntries_notURLClassLoader_withParent() throws Exception {
    URL url = new URL("file:/a");
    URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
    assertEquals(
        ImmutableMap.of(url.toURI(), parent),
        ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
  }

  public void testClassPathEntries_notURLClassLoader_withParentAndGrandParent() throws Exception {
    URL url1 = new URL("file:/a");
    URL url2 = new URL("file:/b");
    URLClassLoader grandParent = new URLClassLoader(new URL[] {url1}, null);
    URLClassLoader parent = new URLClassLoader(new URL[] {url2}, grandParent);
    assertEquals(
        ImmutableMap.of(url1.toURI(), grandParent, url2.toURI(), parent),
        ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
  }

  public void testClassPathEntries_notURLClassLoader_withGrandParent() throws Exception {
    URL url = new URL("file:/a");
    URLClassLoader grandParent = new URLClassLoader(new URL[] {url}, null);
    ClassLoader parent = new ClassLoader(grandParent) {};
    assertEquals(
        ImmutableMap.of(url.toURI(), grandParent),
        ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
  }

  public void testScan_classPathCycle() throws IOException {
    File jarFile = File.createTempFile("with_circular_class_path", ".jar");
    try {
      writeSelfReferencingJarFile(jarFile, "test.txt");
      ClassPath.Scanner scanner = new ClassPath.Scanner();
      scanner.scan(jarFile.toURI(), ClassPathTest.class.getClassLoader());
      assertEquals(1, scanner.getResources().size());
    } finally {
      jarFile.delete();
    }
  }

  public void testScanFromFile_fileNotExists() throws IOException {
    ClassLoader classLoader = ClassPathTest.class.getClassLoader();
    ClassPath.Scanner scanner = new ClassPath.Scanner();
    scanner.scanFrom(new File("no/such/file/anywhere"), classLoader);
    assertThat(scanner.getResources()).isEmpty();
  }

  public void testScanFromFile_notJarFile() throws IOException {
    ClassLoader classLoader = ClassPathTest.class.getClassLoader();
    File notJar = File.createTempFile("not_a_jar", "txt");
    ClassPath.Scanner scanner = new ClassPath.Scanner();
    try {
      scanner.scanFrom(notJar, classLoader);
    } finally {
      notJar.delete();
    }
    assertThat(scanner.getResources()).isEmpty();
  }

  public void testGetClassPathEntry() throws URISyntaxException {
    assertEquals(URI.create("file:/usr/test/dep.jar"),
        ClassPath.Scanner.getClassPathEntry(
            new File("/home/build/outer.jar"), "file:/usr/test/dep.jar"));
    assertEquals(URI.create("file:/home/build/a.jar"),
        ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar"));
    assertEquals(URI.create("file:/home/build/x/y/z"),
        ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z"));
    assertEquals(URI.create("file:/home/build/x/y/z.jar"),
        ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar"));
  }

  public void testGetClassPathFromManifest_nullManifest() {
    assertThat(ClassPath.Scanner.getClassPathFromManifest(new File("some.jar"), null)).isEmpty();
  }

  public void testGetClassPathFromManifest_noClassPath() throws IOException {
    File jarFile = new File("base.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest("")))
        .isEmpty();
  }

  public void testGetClassPathFromManifest_emptyClassPath() throws IOException {
    File jarFile = new File("base.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifestClasspath("")))
        .isEmpty();
  }

  public void testGetClassPathFromManifest_badClassPath() throws IOException {
    File jarFile = new File("base.jar");
    Manifest manifest = manifestClasspath("an_invalid^path");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .isEmpty();
  }

  public void testGetClassPathFromManifest_relativeDirectory() throws IOException {
    File jarFile = new File("base/some.jar");
    // with/relative/directory is the Class-Path value in the mf file.
    Manifest manifest = manifestClasspath("with/relative/dir");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("base/with/relative/dir").toURI());
  }

  public void testGetClassPathFromManifest_relativeJar() throws IOException {
    File jarFile = new File("base/some.jar");
    // with/relative/directory is the Class-Path value in the mf file.
    Manifest manifest = manifestClasspath("with/relative.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("base/with/relative.jar").toURI());
  }

  public void testGetClassPathFromManifest_jarInCurrentDirectory() throws IOException {
    File jarFile = new File("base/some.jar");
    // with/relative/directory is the Class-Path value in the mf file.
    Manifest manifest = manifestClasspath("current.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("base/current.jar").toURI());
  }

  public void testGetClassPathFromManifest_absoluteDirectory() throws IOException {
    File jarFile = new File("base/some.jar");
    Manifest manifest = manifestClasspath("file:/with/absolute/dir");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("/with/absolute/dir").toURI());
  }

  public void testGetClassPathFromManifest_absoluteJar() throws IOException {
    File jarFile = new File("base/some.jar");
    Manifest manifest = manifestClasspath("file:/with/absolute.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("/with/absolute.jar").toURI());
  }

  public void testGetClassPathFromManifest_multiplePaths() throws IOException {
    File jarFile = new File("base/some.jar");
    Manifest manifest = manifestClasspath("file:/with/absolute.jar relative.jar  relative/dir");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(
            new File("/with/absolute.jar").toURI(),
            new File("base/relative.jar").toURI(),
            new File("base/relative/dir").toURI())
        .inOrder();
  }

  public void testGetClassPathFromManifest_leadingBlanks() throws IOException {
    File jarFile = new File("base/some.jar");
    Manifest manifest = manifestClasspath(" relative.jar");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("base/relative.jar").toURI());
  }

  public void testGetClassPathFromManifest_trailingBlanks() throws IOException {
    File jarFile = new File("base/some.jar");
    Manifest manifest = manifestClasspath("relative.jar ");
    assertThat(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest))
        .containsExactly(new File("base/relative.jar").toURI());
  }

  public void testGetClassName() {
    assertEquals("abc.d.Abc", ClassPath.getClassName("abc/d/Abc.class"));
  }

  public void testResourceInfo_of() {
    assertEquals(ClassInfo.class, resourceInfo(ClassPathTest.class).getClass());
    assertEquals(ClassInfo.class, resourceInfo(ClassPath.class).getClass());
    assertEquals(ClassInfo.class, resourceInfo(Nested.class).getClass());
  }

  public void testGetSimpleName() {
    assertEquals("Foo",
        new ClassInfo("Foo.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("Foo",
        new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("Foo",
        new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("",
        new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("Foo",
        new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("",
        new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName());
    assertEquals("Local",
        new ClassInfo("a/b/Bar$1Local.class", getClass().getClassLoader()).getSimpleName());

  }

  public void testGetPackageName() {
    assertEquals("",
        new ClassInfo("Foo.class", getClass().getClassLoader()).getPackageName());
    assertEquals("a.b",
        new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getPackageName());
  }

  private static class Nested {}

  public void testNulls() throws IOException {
    new NullPointerTester().testAllPublicStaticMethods(ClassPath.class);
    new NullPointerTester()
        .testAllPublicInstanceMethods(ClassPath.from(getClass().getClassLoader()));
  }

  private static ClassPath.ClassInfo findClass(
      Iterable<ClassPath.ClassInfo> classes, Class<?> cls) {
    for (ClassPath.ClassInfo classInfo : classes) {
      if (classInfo.getName().equals(cls.getName())) {
        return classInfo;
      }
    }
    throw new AssertionError("failed to find " + cls);
  }

  private static ResourceInfo resourceInfo(Class<?> cls) {
    return ResourceInfo.of(cls.getName().replace('.', '/') + ".class", cls.getClassLoader());
  }

  private static ClassInfo classInfo(Class<?> cls) {
    return classInfo(cls, cls.getClassLoader());
  }

  private static ClassInfo classInfo(Class<?> cls, ClassLoader classLoader) {
    return new ClassInfo(cls.getName().replace('.', '/') + ".class", classLoader);
  }

  private static Manifest manifestClasspath(String classpath) throws IOException {
    return manifest("Class-Path: " + classpath + "\n");
  }

  private static void writeSelfReferencingJarFile(File jarFile, String... entries)
      throws IOException {
    Manifest manifest = new Manifest();
    // Without version, the manifest is silently ignored. Ugh!
    manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, jarFile.getName());

    Closer closer = Closer.create();
    try {
      FileOutputStream fileOut = closer.register(new FileOutputStream(jarFile));
      JarOutputStream jarOut = closer.register(new JarOutputStream(fileOut));
      for (String entry : entries) {
        jarOut.putNextEntry(new ZipEntry(entry));
        Resources.copy(ClassPathTest.class.getResource(entry), jarOut);
        jarOut.closeEntry();
      }
    } catch (Throwable e) {
      throw closer.rethrow(e);
    } finally {
      closer.close();
    }
  }

  private static Manifest manifest(String content) throws IOException {
    InputStream in = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII));
    Manifest manifest = new Manifest();
    manifest.read(in);
    return manifest;
  }
}
TOP

Related Classes of com.google.common.reflect.ClassPathTest$Nested

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.