blob: a776145e1ae6e74ea5059d58176a0890d3be901d [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* 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.facebook.buck.android;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Collections;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* This Supplier returns a list of all the ClassNode objects in a set of jar files.
*/
class ClassNodeListSupplier implements Supplier<ImmutableList<ClassNode>> {
private final Iterable<Path> jarPaths;
private ClassNodeListSupplier(Iterable<Path> jarPaths) {
this.jarPaths = jarPaths;
}
public static Supplier<ImmutableList<ClassNode>> createMemoized(Iterable<Path> jarPaths) {
return Suppliers.memoize(new ClassNodeListSupplier(jarPaths));
}
@Override
public ImmutableList<ClassNode> get() {
return loadAllClassNodes();
}
private ImmutableList<ClassNode> loadAllClassNodes() {
ImmutableList.Builder<ClassNode> builder = ImmutableList.builder();
for (Path jarPath : jarPaths) {
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
loadClassNodes(jarFile, builder);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
return builder.build();
}
private void loadClassNodes(JarFile jarFile, ImmutableList.Builder<ClassNode> builder)
throws IOException {
for (JarEntry entry : Collections.list(jarFile.entries())) {
String name = entry.getName();
if (entry.isDirectory() || (name == null) || !name.endsWith(".class")) {
continue;
}
ClassNode node = new ClassNode();
try (InputStream stream = jarFile.getInputStream(entry)) {
ClassReader reader = new ClassReader(stream);
reader.accept(node, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
}
builder.add(node);
}
}
}