All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.spotify.missinglink.ArtifactLoader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2015 Spotify AB
 *
 * 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.spotify.missinglink;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;

import com.spotify.missinglink.datamodel.Artifact;
import com.spotify.missinglink.datamodel.ArtifactBuilder;
import com.spotify.missinglink.datamodel.ArtifactName;
import com.spotify.missinglink.datamodel.ClassTypeDescriptor;
import com.spotify.missinglink.datamodel.DeclaredClass;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static java.util.stream.Collectors.toList;

public class ArtifactLoader {

  /** Load artifact at path, using path name as artifactId */
  public Artifact load(File path) throws IOException {
    return load(new ArtifactName(path.getName()), path);
  }

  /** Load artifact at path with a custom artifactId */
  public Artifact load(ArtifactName artifactName, File path) throws IOException {
    Preconditions.checkArgument(path.exists(), "Path must exist: " + path);
    Preconditions.checkArgument(path.isFile() || path.isDirectory(),
        "Path must be a file or directory: " + path);

    if (path.isFile()) {
      JarFile jarFile;
      try {
        jarFile = new JarFile(path);
      } catch (IOException e) {
        throw new RuntimeException("Could not load " + path, e);
      }
      ImmutableMap.Builder classes =
          new ImmutableMap.Builder<>();
      // Why would anyone bother updating this API to add support for iterators? Way too much work..
      Enumeration entries = jarFile.entries();
      while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();
        if (entry.getName().endsWith(".class")) {
          try {
            DeclaredClass cl = new ClassLoader(jarFile.getInputStream(entry)).load();
            classes.put(cl.className(), cl);
          } catch (Exception e) {
            System.err.println("Could not load " + entry.getName() + " from " + path);
          }
        }
      }
      return artifact(artifactName, classes);
    } else {
      ImmutableMap.Builder classes =
          new ImmutableMap.Builder<>();

      List classFilesInDir = Files.walk(path.toPath())
          .map(Path::toFile)
          .filter(file -> file.isFile() && file.getName().endsWith(".class"))
          .collect(toList());

      for (File file : classFilesInDir) {
        try (FileInputStream fis = new FileInputStream(file)) {
          DeclaredClass cl = new ClassLoader(fis).load();
          classes.put(cl.className(), cl);
        }
      }
      return artifact(artifactName, classes);
    }
  }

  private static Artifact artifact(ArtifactName name,
                                   Builder classes) {
    return new ArtifactBuilder()
        .name(name)
        .classes(classes.build())
        .build();
  }

  public static void main(String[] args) throws Exception {
    ArtifactLoader l = new ArtifactLoader();
    System.out.println(l.load(new File("core/src/test/resources/ArtifactLoaderTest.jar")));
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy